// 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;
    }
  }
}
