#!/usr/bin/env python2.7
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""fd.py is a fascinating directory changer to save your time in typing.

Use shell function "fd()" to enable autocompletion.
Use "fd.py" directly for without autocompletion.

See examples by
$ fd.py --help

fd stores two helper files, fd.txt and fd.pickle in $FUCHSIA_DIR/out/.
If that directory does not exists, fd will create one.
"""

from __future__ import print_function

import argparse
import os
import pickle
import sys
import termios
import tty

SEARCH_BASE = os.environ['FUCHSIA_DIR']  # or 'HOME'
STORE_DIR = SEARCH_BASE + '/out/'
DIRS_FILE = STORE_DIR + 'fd.txt'
PICKLE_FILE = STORE_DIR + 'fd.pickle'

EXCLUDE_DIRS = [
    '"*/.git"', './build', './out', './prebuilt', './third_party',
    './zircon/build', './zircon/prebuilt', './cmake-build-debug', './zircon/third_party',
]


def eprint(*args, **kwargs):
  print(*args, file=sys.stderr, **kwargs)


class Trie(object):
  """Class Trie.
  """

  def __init__(self):
    self.name = ''  # != path up to here from the root. Key is a valid
    # complete one.
    self.vals = []
    self.kids = {}

  def __getitem__(self, name, idx=0):
    if self.name == name:
      return self.vals
    if idx == name.__len__() or name[idx] not in self.kids:
      return None
    return self.kids[name[idx]].__getitem__(name, idx + 1)

  def __setitem__(self, name, val, idx=0):
    if idx < name.__len__():
      self.kids.setdefault(name[idx], Trie()).__setitem__(name, val, idx + 1)
      return
    self.name = name
    self.vals.append(val)

  def __contains__(self, name):
    return self[name] is not None

  def walk(self):
    descendants = []
    if self.name:
      descendants.append(self.name)
    for k in self.kids:
      descendants.extend(self.kids[k].walk())
    return descendants

  def prefixed(self, name, idx=0):
    if idx < name.__len__():
      if name[idx] in self.kids:
        return self.kids[name[idx]].prefixed(name, idx + 1)
      return []

    return self.walk()


def build_trie():
  """build trie.

  Returns:
    Trie
  """

  def build_find_cmd():
    paths = []
    for path in EXCLUDE_DIRS:
      paths.append('{} {}'.format('-path', path))
    return (r'cd {}; find . \( {} \) -prune -o -type d -print > '
            '{}').format(SEARCH_BASE, ' -o '.join(paths), DIRS_FILE)

  if not os.path.exists(STORE_DIR):
    os.makedirs(STORE_DIR)

  cmd_str = build_find_cmd()
  os.system(cmd_str)

  t = Trie()
  with open(DIRS_FILE, 'r') as f:
    for line in f:
      line = line[2:][:-1]
      tokens = line.split('/')
      if tokens.__len__() == 0:
        continue
      target = tokens[-1]

      t[target] = line

  return t


def get_trie():
  """get_trie.

  Returns:
    trie
  """

  def save_pickle(obj):
    with open(PICKLE_FILE, 'wb+') as f:
      pickle.dump(obj, f, protocol=pickle.HIGHEST_PROTOCOL)

  def load_pickle():
    with open(PICKLE_FILE, 'rb') as f:
      return pickle.load(f)

  if os.path.exists(PICKLE_FILE):
    return load_pickle()

  t = build_trie()
  save_pickle(t)
  return t


def button(idx):
  """button maps idx to an ascii value.
  """
  ascii = 0
  if 0 <= idx <= 8:
    ascii = ord('1') + idx
  elif 9 <= idx <= 34:
    ascii = ord('a') + idx - 9
  elif 35 <= idx <= 60:
    ascii = ord('A') + idx - 35
  elif 61 <= idx <= 75:
    ascii = ord('!') + idx - 61
  return str(unichr(ascii))


def get_button():  # Unix way
  fd = sys.stdin.fileno()
  old_settings = termios.tcgetattr(fd)
  try:
    tty.setraw(sys.stdin.fileno())
    ch = sys.stdin.read(1)
  finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
  return ch


def choose_options(t, key, choice):
  # Build options by the given key
  if key in t:
    options = t[key]
  else:
    prefixed_keys = t.prefixed(key)
    options = []
    for pk in prefixed_keys:
      options.extend(t[pk])

  options = sorted(options)
  if options.__len__() == 0:
    eprint('No such directory: {}'.format(key))
    return None
  elif options.__len__() == 1:
    return options[0]
  elif options.__len__() > 75:  # See def button() for the limit.
    eprint('Too many ({}) results for "{}". '
           'Refine your prefix or time to buy 4K '
           'monitor\n'.format(options.__len__(), key))
    return None

  def list_choices(l):
    for i in range(l.__len__()):
      eprint('[{}] {}'.format(button(i), l[i]))
    eprint()

  choice_dic = {}
  for idx, val in enumerate(options):
    choice_dic[button(idx)] = val

  if choice is not None and choice not in choice_dic:
    # Invalid pre-choice
    eprint('Choice "{}" not available\n'.format(choice))

  if choice not in choice_dic:
    list_choices(options)
    choice = get_button()
    if choice not in choice_dic:
      return None

  return choice_dic[choice]


def main():

  def parse_cmdline():
    example_commands = """

[eg] # Use "fd" for autocompletion (See //scripts/fx-env.sh)
  $ fd ral        # change directory to an only option: ralink
  $ fd wlan       # shows all "wlan" directories and ask to choose
  $ fd wlan 3     # change directory matching to option 3 of "fd wlan"
  $ fd [TAB]      # Autocomplete subdirectories from the current directory
  $ fd //[TAB]    # Autocomplete subdirectories from ${FUCHSIA_DIR}
  $ fd --rebuild  # rebuilds the directory structure cache
"""
    p = argparse.ArgumentParser(
        description='A fascinating directory changer',
        epilog=example_commands,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    p.add_argument(
        '--rebuild', action='store_true', help='rebuild the directory DB')
    p.add_argument('--base', type=str, default=None)
    p.add_argument('target', nargs='?', default='')
    p.add_argument('choice', nargs='?', default=None)

    # Redirect help messages to stderr
    if len(sys.argv) == 2:
      if sys.argv[1] in ['-h', '--help']:
        eprint(p.format_help())
        print('.')  # Stay at the current directory
        sys.exit(0)

    return p.parse_args()

  def get_abs_path(relative_dir):
    if relative_dir is not None:
      return os.path.join(SEARCH_BASE, relative_dir)
    return os.getcwd()

  def derive_dest(target):
    if not target:
      # To test if this command was invoked just to rebuild
      return get_abs_path('.') if args.rebuild is False else os.getcwd()

    if target[:2] == '//':
      target = target[2:]

    candidate = target

    # Do not guess-work when the user specifies an option to intend to use.
    # Do guess work otherwise.
    if not args.choice:
      if os.path.exists(candidate):
        return candidate

      candidate = get_abs_path(target)
      if os.path.exists(candidate):
        return candidate

      candidate = os.path.abspath(target)
      if os.path.exists(candidate):
        return candidate

    t = get_trie()
    return get_abs_path(choose_options(t, target, args.choice))

  args = parse_cmdline()
  if args.base:
    global SEARCH_BASE
    SEARCH_BASE = args.base

  if args.rebuild:
    os.remove(PICKLE_FILE)

  dest = derive_dest(args.target)
  dest = os.path.normpath(dest)
  print(dest)


if __name__ == '__main__':
  try:
    main()
  except Exception as e:  # Catch all
    eprint(e.message, e.args)
    print('.')  # Stay at the current directory upon exception
