#!/usr/bin/env python
# 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', './buildtools', './out', './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
