// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of cli;

// Splits a line into a list of string args.  Each arg retains any
// trailing whitespace so that we can reconstruct the original command
// line from the pieces.
List<String> _splitLine(String line) {
  line = line.trimLeft();
  var args = [];
  var codes = line.codeUnits;

  int pos = 0;
  while (pos < line.length) {
    int startPos = pos;

    // Advance to end of word.
    for (; pos < line.length && line[pos] != ' '; pos++);

    // Advance to end of spaces.
    for (; pos < line.length && line[pos] == ' '; pos++);

    args.add(line.substring(startPos, pos));
  }
  return args;
}

// Concatenates the first 'count' args.
String _concatArgs(List<String> args, int count) {
  if (count == 0) {
    return '';
  }
  return '${args.sublist(0, count).join('')}';
}

// Shared functionality for RootCommand and Command.
abstract class _CommandBase {
  _CommandBase(List<Command> children) {
    assert(children != null);
    _children.addAll(children);
    for (var child in _children) {
      child._parent = this;
    }
  }

  // A command may optionally have sub-commands.
  List<Command> _children = [];

  _CommandBase _parent;
  int get _depth => (_parent == null ? 0 : _parent._depth + 1);

  // Override in subclasses to provide command-specific argument completion.
  //
  // Given a list of arguments to this command, provide a list of
  // possible completions for those arguments.
  Future<List<String>> complete(List<String> args) => new Future.value([]);

  // Override in subclasses to provide command-specific execution.
  Future run(List<String> args);

  // Returns a list of local subcommands which match the args.
  List<Command> _matchLocal(String argWithSpace, bool preferExact) {
    var matches = new List<Command>();
    var arg = argWithSpace.trimRight();
    for (var child in _children) {
      if (child.name.startsWith(arg)) {
        if (preferExact && ((child.name == arg) || (child.alias == arg))) {
          return [child];
        }
        matches.add(child);
      }
    }
    return matches;
  }

  // Returns the set of commands could be triggered by a list of
  // arguments.
  List<Command> _match(List<String> args, bool preferExact) {
    if (args.isEmpty) {
      return [];
    }    
    bool lastArg = (args.length == 1);
    var matches = _matchLocal(args[0], !lastArg || preferExact);
    if (matches.isEmpty) {
      return [];
    } else if (matches.length == 1) {
      var childMatches =  matches[0]._match(args.sublist(1), preferExact);
      if (childMatches.isEmpty) {
        return matches;
      } else {
        return childMatches;
      }
    } else {
      return matches;
    }
  }

  // Builds a list of completions for this command.
  Future<List<String>> _buildCompletions(List<String> args,
                                         bool addEmptyString) {
    return complete(args.sublist(_depth, args.length))
      .then((completions) {
        if (addEmptyString && completions.isEmpty &&
            args[args.length - 1] == '') {
          // Special case allowance for an empty particle at the end of
          // the command.
          completions = [''];
        }
        var prefix = _concatArgs(args, _depth);
        return completions.map((str) => '${prefix}${str}').toList();
      });
  }

}

// The root of a tree of commands.
class RootCommand extends _CommandBase {
  RootCommand(List<Command> children) : super(children);

  // Provides a list of possible completions for a line of text.
  Future<List<String>> completeCommand(String line) {
    var args = _splitLine(line);
    bool showAll = line.endsWith(' ') || args.isEmpty;
    if (showAll) {
      // Adding an empty string to the end causes us to match all
      // subcommands of the last command.
      args.add('');
    }
    var commands =  _match(args, false);
    if (commands.isEmpty) {
      // No matching commands.
      return new Future.value([]);
    }
    int matchLen = commands[0]._depth;
    if (matchLen < args.length) {
      // We were able to find a command which matches a prefix of the
      // args, but not the full list.
      if (commands.length == 1) {
        // The matching command is unique.  Attempt to provide local
        // argument completion from the command.
        return commands[0]._buildCompletions(args, true);
      } else {
        // An ambiguous prefix match leaves us nowhere.  The user is
        // typing a bunch of stuff that we don't know how to complete.
        return new Future.value([]);
      }
    }

    // We have found a set of commands which match all of the args.
    // Return the completions strings.
    var prefix = _concatArgs(args, args.length - 1);
    var completions =
        commands.map((command) => '${prefix}${command.name} ').toList();
    if (showAll && matchLen == args.length) {
      // If we are showing all possiblities, also include local
      // completions for the parent command.
      return commands[0]._parent._buildCompletions(args, false)
        .then((localCompletions) {
          completions.addAll(localCompletions);
          return completions;
        });
    }
    return new Future.value(completions);
  }

  // Runs a command.
  Future runCommand(String line) {
    _historyAdvance(line);
    var args = _splitLine(line);
    var commands =  _match(args, true);
    if (commands.isEmpty) {
      // TODO(turnidge): Add a proper exception class for this.
      return new Future.error('notfound');
    } else if (commands.length == 1) {
      return commands[0].run(args.sublist(commands[0]._depth));
    } else {
      // TODO(turnidge): Add a proper exception class for this.
      return new Future.error('ambiguous');
    }
  }

  // Find all matching commands.  Useful for implementing help systems.
  List<Command> matchCommand(List<String> args, bool preferExact) {
    if (args.isEmpty) {
      // Adding an empty string to the end causes us to match all
      // subcommands of the last command.
      args.add('');
    }
    return _match(args, preferExact);
  }

  // Command line history always contains one slot to hold the current
  // line, so we start off with one entry.
  List<String> history = [''];
  int historyPos = 0;

  String historyPrev(String line) {
    if (historyPos == 0) {
      return line;
    }
    history[historyPos] = line;
    historyPos--;
    return history[historyPos];
  }

  String historyNext(String line) {
    if (historyPos == history.length - 1) {
      return line;
    }
    history[historyPos] = line;
    historyPos++;
    return history[historyPos];
  }

  void _historyAdvance(String line) {
    // Replace the last history line.
    historyPos = history.length - 1;
    history[historyPos] = line;

    // Create an empty spot for the next line.
    history.add('');
    historyPos++;
  }

  Future run(List<String> args) {
    throw 'should-not-execute-the-root-command';
  }

  toString() => 'RootCommand';
}

// A node in the command tree.
abstract class Command extends _CommandBase {
  Command(this.name, List<Command> children) : super(children);

  final String name;
  String alias;

  String get fullName {
    if (_parent is RootCommand) {
      return name;
    } else {
      Command parent = _parent;
      return '${parent.fullName} $name';
    }
  }

  toString() => 'Command(${name})';
}
