// Copyright (c) 2013, 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.

library args.src.parser;

import '../args.dart';

final _SOLO_OPT = new RegExp(r'^-([a-zA-Z0-9])$');
final _ABBR_OPT = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$');
final _LONG_OPT = new RegExp(r'^--([a-zA-Z\-_0-9]+)(=(.*))?$');

/**
 * The actual parsing class. Unlike [ArgParser] which is really more an "arg
 * grammar", this is the class that does the parsing and holds the mutable
 * state required during a parse.
 */
class Parser {
  /**
   * If parser is parsing a command's options, this will be the name of the
   * command. For top-level results, this returns `null`.
   */
  final String commandName;

  /**
   * The parser for the supercommand of this command parser, or `null` if this
   * is the top-level parser.
   */
  final Parser parent;

  /** The grammar being parsed. */
  final ArgParser grammar;

  /** The arguments being parsed. */
  final List<String> args;

  /** The accumulated parsed options. */
  final Map results = {};

  Parser(this.commandName, this.grammar, this.args, [this.parent]);

  /** The current argument being parsed. */
  String get current => args[0];

  /** Parses the arguments. This can only be called once. */
  ArgResults parse() {
    var commandResults = null;

    // Initialize flags to their defaults.
    grammar.options.forEach((name, option) {
      if (option.allowMultiple) {
        results[name] = [];
      } else {
        results[name] = option.defaultValue;
      }
    });

    // Parse the args.
    while (args.length > 0) {
      if (current == '--') {
        // Reached the argument terminator, so stop here.
        args.removeAt(0);
        break;
      }

      // Try to parse the current argument as a command. This happens before
      // options so that commands can have option-like names.
      var command = grammar.commands[current];
      if (command != null) {
        var commandName = args.removeAt(0);
        var commandParser = new Parser(commandName, command, args, this);
        commandResults = commandParser.parse();
        continue;
      }

      // Try to parse the current argument as an option. Note that the order
      // here matters.
      if (parseSoloOption()) continue;
      if (parseAbbreviation(this)) continue;
      if (parseLongOption()) continue;

      // If we got here, the argument doesn't look like an option, so stop.
      break;
    }

    // Set unspecified multivalued arguments to their default value,
    // if any, and invoke the callbacks.
    grammar.options.forEach((name, option) {
      if (option.allowMultiple &&
          results[name].length == 0 &&
          option.defaultValue != null) {
        results[name].add(option.defaultValue);
      }
      if (option.callback != null) option.callback(results[name]);
    });

    // Add in the leftover arguments we didn't parse to the innermost command.
    var rest = args.toList();
    args.clear();
    return new ArgResults(results, commandName, commandResults, rest);
  }

  /**
   * Pulls the value for [option] from the second argument in [args]. Validates
   * that there is a valid value there.
   */
  void readNextArgAsValue(Option option) {
    // Take the option argument from the next command line arg.
    validate(args.length > 0, 'Missing argument for "${option.name}".');

    // Make sure it isn't an option itself.
    validate(!_ABBR_OPT.hasMatch(current) && !_LONG_OPT.hasMatch(current),
        'Missing argument for "${option.name}".');

    setOption(results, option, current);
    args.removeAt(0);
  }

  /**
   * Tries to parse the current argument as a "solo" option, which is a single
   * hyphen followed by a single letter. We treat this differently than
   * collapsed abbreviations (like "-abc") to handle the possible value that
   * may follow it.
   */
  bool parseSoloOption() {
    var soloOpt = _SOLO_OPT.firstMatch(current);
    if (soloOpt == null) return false;

    var option = grammar.findByAbbreviation(soloOpt[1]);
    if (option == null) {
      // Walk up to the parent command if possible.
      validate(
          parent != null, 'Could not find an option or flag "-${soloOpt[1]}".');
      return parent.parseSoloOption();
    }

    args.removeAt(0);

    if (option.isFlag) {
      setOption(results, option, true);
    } else {
      readNextArgAsValue(option);
    }

    return true;
  }

  /**
   * Tries to parse the current argument as a series of collapsed abbreviations
   * (like "-abc") or a single abbreviation with the value directly attached
   * to it (like "-mrelease").
   */
  bool parseAbbreviation(Parser innermostCommand) {
    var abbrOpt = _ABBR_OPT.firstMatch(current);
    if (abbrOpt == null) return false;

    // If the first character is the abbreviation for a non-flag option, then
    // the rest is the value.
    var c = abbrOpt[1].substring(0, 1);
    var first = grammar.findByAbbreviation(c);
    if (first == null) {
      // Walk up to the parent command if possible.
      validate(
          parent != null, 'Could not find an option with short name "-$c".');
      return parent.parseAbbreviation(innermostCommand);
    } else if (!first.isFlag) {
      // The first character is a non-flag option, so the rest must be the
      // value.
      var value = '${abbrOpt[1].substring(1)}${abbrOpt[2]}';
      setOption(results, first, value);
    } else {
      // If we got some non-flag characters, then it must be a value, but
      // if we got here, it's a flag, which is wrong.
      validate(
          abbrOpt[2] == '',
          'Option "-$c" is a flag and cannot handle value '
          '"${abbrOpt[1].substring(1)}${abbrOpt[2]}".');

      // Not an option, so all characters should be flags.
      // We use "innermostCommand" here so that if a parent command parses the
      // *first* letter, subcommands can still be found to parse the other
      // letters.
      for (var i = 0; i < abbrOpt[1].length; i++) {
        var c = abbrOpt[1].substring(i, i + 1);
        innermostCommand.parseShortFlag(c);
      }
    }

    args.removeAt(0);
    return true;
  }

  void parseShortFlag(String c) {
    var option = grammar.findByAbbreviation(c);
    if (option == null) {
      // Walk up to the parent command if possible.
      validate(
          parent != null, 'Could not find an option with short name "-$c".');
      parent.parseShortFlag(c);
      return;
    }

    // In a list of short options, only the first can be a non-flag. If
    // we get here we've checked that already.
    validate(
        option.isFlag, 'Option "-$c" must be a flag to be in a collapsed "-".');

    setOption(results, option, true);
  }

  /**
   * Tries to parse the current argument as a long-form named option, which
   * may include a value like "--mode=release" or "--mode release".
   */
  bool parseLongOption() {
    var longOpt = _LONG_OPT.firstMatch(current);
    if (longOpt == null) return false;

    var name = longOpt[1];
    var option = grammar.options[name];
    if (option != null) {
      args.removeAt(0);
      if (option.isFlag) {
        validate(longOpt[3] == null,
            'Flag option "$name" should not be given a value.');

        setOption(results, option, true);
      } else if (longOpt[3] != null) {
        // We have a value like --foo=bar.
        setOption(results, option, longOpt[3]);
      } else {
        // Option like --foo, so look for the value as the next arg.
        readNextArgAsValue(option);
      }
    } else if (name.startsWith('no-')) {
      // See if it's a negated flag.
      name = name.substring('no-'.length);
      option = grammar.options[name];
      if (option == null) {
        // Walk up to the parent command if possible.
        validate(parent != null, 'Could not find an option named "$name".');
        return parent.parseLongOption();
      }

      args.removeAt(0);
      validate(option.isFlag, 'Cannot negate non-flag option "$name".');
      validate(option.negatable, 'Cannot negate option "$name".');

      setOption(results, option, false);
    } else {
      // Walk up to the parent command if possible.
      validate(parent != null, 'Could not find an option named "$name".');
      return parent.parseLongOption();
    }

    return true;
  }

  /**
   * Called during parsing to validate the arguments. Throws a
   * [FormatException] if [condition] is `false`.
   */
  validate(bool condition, String message) {
    if (!condition) throw new FormatException(message);
  }

  /** Validates and stores [value] as the value for [option]. */
  setOption(Map results, Option option, value) {
    // See if it's one of the allowed values.
    if (option.allowed != null) {
      validate(option.allowed.any((allow) => allow == value),
          '"$value" is not an allowed value for option "${option.name}".');
    }

    if (option.allowMultiple) {
      results[option.name].add(value);
    } else {
      results[option.name] = value;
    }
  }
}
