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

import '../messages/codes.dart';
import 'resolve_input_uri.dart';

class CommandLineProblem {
  final Message message;

  CommandLineProblem(this.message);

  CommandLineProblem.deprecated(String message)
      : this(templateUnspecified.withArguments(message));

  String toString() => message.message;
}

class ParsedOptions {
  final Map<String, dynamic> options = <String, dynamic>{};
  final List<String> arguments = <String>[];
  final Map<String, String> defines = <String, String>{};

  String toString() => "ParsedArguments($options, $arguments)";

  /// Returns arguments stored as line separated text.
  static List<String> readOptionsFile(String optionsFile) {
    return optionsFile
        .split('\n')
        .map((String line) => line.trim())
        .where((line) => line.isNotEmpty)
        .toList();
  }

  /// Parses a list of command-line [arguments] into options and arguments.
  ///
  /// An /option/ is something that, normally, starts with `-` or `--` (one or
  /// two dashes). However, as a special case `/?` and `/h` are also recognized
  /// as options for increased compatibility with Windows. An option can have a
  /// value.
  ///
  /// An /argument/ is something that isn't an option, for example, a file name.
  ///
  /// The specification is a map of options to one of the following values:
  /// * the type literal `Uri`, representing an option value of type [Uri],
  /// * the type literal `int`, representing an option value of type [int],
  /// * the bool literal `false`, representing a boolean option that is turned
  ///   off by default,
  /// * the bool literal `true, representing a boolean option that is turned on
  ///   by default,
  /// * or the string literal `","`, representing a comma-separated list of
  ///   values.
  ///
  /// If [arguments] contains `"--"`, anything before is parsed as options, and
  /// arguments; anything following is treated as arguments (even if starting
  /// with, for example, a `-`).
  ///
  /// If an option isn't found in [specification], an error is thrown.
  ///
  /// Boolean options do not require an option value, but an optional value can
  /// be provided using the forms `--option=value` where `value` can be `true`
  /// or `yes` to turn on the option, or `false` or `no` to turn it off.  If no
  /// option value is specified, a boolean option is turned on.
  ///
  /// All other options require an option value, either on the form `--option
  /// value` or `--option=value`.
  static ParsedOptions parse(List<String> arguments, List<Option>? options) {
    options ??= [];
    Map<String, ValueSpecification>? specification = {};
    void addSpec(String flag, ValueSpecification spec) {
      if (specification.containsKey(flag)) {
        throw new CommandLineProblem.deprecated("Duplicate option '${flag}'.");
      }
      specification[flag] = spec;
    }

    for (Option option in options) {
      addSpec(option.flag, option.spec);
      for (String alias in option.aliases) {
        addSpec(alias, new AliasValue(option.flag));
      }
    }
    ParsedOptions result = new ParsedOptions();
    int index = arguments.indexOf("--");
    Iterable<String> nonOptions = const <String>[];
    Iterator<String> iterator = arguments.iterator;
    if (index != -1) {
      nonOptions = arguments.skip(index + 1);
      iterator = arguments.take(index).iterator;
    }
    while (iterator.moveNext()) {
      String argument = iterator.current;
      if (argument.startsWith("-") || argument == "/?" || argument == "/h") {
        String? value;
        if (argument.startsWith("-D")) {
          value = argument.substring("-D".length);
          argument = "-D";
        } else {
          index = argument.indexOf("=");
          if (index != -1) {
            value = argument.substring(index + 1);
            argument = argument.substring(0, index);
          }
        }
        ValueSpecification? valueSpecification = specification[argument];
        if (valueSpecification == null) {
          throw new CommandLineProblem.deprecated(
              "Unknown option '$argument'.");
        }
        String canonicalArgument = argument;
        if (valueSpecification.alias != null) {
          canonicalArgument = valueSpecification.alias as String;
          valueSpecification = specification[valueSpecification.alias];
        }
        if (valueSpecification == null) {
          throw new CommandLineProblem.deprecated(
              "Unknown option alias '$canonicalArgument'.");
        }
        final bool requiresValue = valueSpecification.requiresValue;
        if (requiresValue && value == null) {
          if (!iterator.moveNext()) {
            throw new CommandLineProblem(
                templateFastaCLIArgumentRequired.withArguments(argument));
          }
          value = iterator.current;
        }
        valueSpecification.processValue(
            result, canonicalArgument, argument, value);
      } else {
        result.arguments.add(argument);
      }
    }
    specification.forEach((String key, ValueSpecification value) {
      if (value.defaultValue != null) {
        result.options[key] ??= value.defaultValue;
      }
    });
    result.arguments.addAll(nonOptions);
    return result;
  }
}

abstract class ValueSpecification<T> {
  const ValueSpecification();

  String? get alias => null;

  T? get defaultValue => null;

  bool get requiresValue => true;

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value);
}

class AliasValue<T> extends ValueSpecification<T> {
  final String alias;

  const AliasValue(this.alias);

  bool get requiresValue =>
      throw new UnsupportedError("AliasValue.requiresValue");

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    throw new UnsupportedError("AliasValue.processValue");
  }
}

class UriValue extends ValueSpecification<Uri?> {
  const UriValue();

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    if (result.options.containsKey(canonicalArgument)) {
      throw new CommandLineProblem.deprecated(
          "Multiple values for '$argument': "
          "'${result.options[canonicalArgument]}' and '$value'.");
    }
    // TODO(ahe): resolve Uris lazily, so that schemes provided by
    // other flags can be used for parsed command-line arguments too.
    result.options[canonicalArgument] = resolveInputUri(value!);
  }
}

class StringValue extends ValueSpecification<String?> {
  final String? defaultValue;

  const StringValue({this.defaultValue});

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    if (result.options.containsKey(canonicalArgument)) {
      throw new CommandLineProblem.deprecated(
          "Multiple values for '$argument': "
          "'${result.options[canonicalArgument]}' and '$value'.");
    }
    result.options[canonicalArgument] = value!;
  }
}

class BoolValue extends ValueSpecification<bool> {
  final bool defaultValue;

  const BoolValue(this.defaultValue);

  bool get requiresValue => false;

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    if (result.options.containsKey(canonicalArgument)) {
      throw new CommandLineProblem.deprecated(
          "Multiple values for '$argument': "
          "'${result.options[canonicalArgument]}' and '$value'.");
    }
    bool parsedValue;
    if (value == null || value == "true" || value == "yes") {
      parsedValue = true;
    } else if (value == "false" || value == "no") {
      parsedValue = false;
    } else {
      throw new CommandLineProblem.deprecated(
          "Value for '$argument' is '$value', "
          "but expected one of: 'true', 'false', 'yes', or 'no'.");
    }
    result.options[canonicalArgument] = parsedValue;
  }
}

class IntValue extends ValueSpecification<int?> {
  final int? defaultValue;
  final int? noArgValue;

  const IntValue({this.defaultValue, this.noArgValue});

  bool get requiresValue => noArgValue == null;

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    if (result.options.containsKey(canonicalArgument)) {
      throw new CommandLineProblem.deprecated(
          "Multiple values for '$argument': "
          "'${result.options[canonicalArgument]}' and '$value'.");
    }
    int? parsedValue = noArgValue;
    if (value != null) {
      parsedValue = int.tryParse(value);
    }
    if (parsedValue == null) {
      throw new CommandLineProblem.deprecated(
          "Value for '$argument', '$value', isn't an int.");
    }
    result.options[canonicalArgument] = parsedValue;
  }
}

class DefineValue extends ValueSpecification<Map<String, String>> {
  const DefineValue();

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    int index = value!.indexOf('=');
    String name;
    String expression;
    if (index != -1) {
      name = value.substring(0, index);
      expression = value.substring(index + 1);
    } else {
      name = value;
      expression = value;
    }
    result.defines[name] = expression;
  }
}

class StringListValue extends ValueSpecification<List<String>?> {
  const StringListValue();

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    List<String> values = result.options[canonicalArgument] ??= <String>[];
    values.addAll(value!.split(","));
  }
}

class UriListValue extends ValueSpecification<List<Uri>?> {
  const UriListValue();

  void processValue(ParsedOptions result, String canonicalArgument,
      String argument, String? value) {
    List<Uri> values = result.options[canonicalArgument] ??= <Uri>[];
    values.addAll(value!.split(",").map(resolveInputUri));
  }
}

class Option<T> {
  final String flag;

  final ValueSpecification<T?> spec;

  final bool isDefines;

  final List<String> aliases;

  const Option(this.flag, this.spec,
      {this.isDefines: false, this.aliases: const []});

  T read(ParsedOptions parsedOptions) =>
      (isDefines ? parsedOptions.defines : parsedOptions.options[flag]) as T;
}
