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

/// Creates a new [Option].
///
/// Since [Option] doesn't have a public constructor, this lets `ArgParser`
/// get to it. This function isn't exported to the public API of the package.
Option newOption(
    String name,
    String? abbr,
    String? help,
    String? valueHelp,
    Iterable<String>? allowed,
    Map<String, String>? allowedHelp,
    defaultsTo,
    Function? callback,
    OptionType type,
    {bool? negatable,
    bool? splitCommas,
    bool mandatory = false,
    bool hide = false,
    List<String> aliases = const []}) {
  return Option._(name, abbr, help, valueHelp, allowed, allowedHelp, defaultsTo,
      callback, type,
      negatable: negatable,
      splitCommas: splitCommas,
      mandatory: mandatory,
      hide: hide,
      aliases: aliases);
}

/// A command-line option.
///
/// This represents both boolean flags and options which take a value.
class Option {
  /// The name of the option that the user passes as an argument.
  final String name;

  /// A single-character string that can be used as a shorthand for this option.
  ///
  /// For example, `abbr: "a"` will allow the user to pass `-a value` or
  /// `-avalue`.
  final String? abbr;

  /// A description of this option.
  final String? help;

  /// A name for the value this option takes.
  final String? valueHelp;

  /// A list of valid values for this option.
  final List<String>? allowed;

  /// A map from values in [allowed] to documentation for those values.
  final Map<String, String>? allowedHelp;

  /// The value this option will have if the user doesn't explicitly pass it.
  final dynamic defaultsTo;

  /// Whether this flag's value can be set to `false`.
  ///
  /// For example, if [name] is `flag`, the user can pass `--no-flag` to set its
  /// value to `false`.
  ///
  /// This is `null` unless [type] is [OptionType.flag].
  final bool? negatable;

  /// The callback to invoke with the option's value when the option is parsed.
  final Function? callback;

  /// Whether this is a flag, a single value option, or a multi-value option.
  final OptionType type;

  /// Whether multiple values may be passed by writing `--option a,b` in
  /// addition to `--option a --option b`.
  final bool splitCommas;

  /// Whether this option must be provided for correct usage.
  final bool mandatory;

  /// Whether this option should be hidden from usage documentation.
  final bool hide;

  /// All aliases for [name].
  final List<String> aliases;

  /// Whether the option is boolean-valued flag.
  bool get isFlag => type == OptionType.flag;

  /// Whether the option takes a single value.
  bool get isSingle => type == OptionType.single;

  /// Whether the option allows multiple values.
  bool get isMultiple => type == OptionType.multiple;

  Option._(
      this.name,
      this.abbr,
      this.help,
      this.valueHelp,
      Iterable<String>? allowed,
      Map<String, String>? allowedHelp,
      this.defaultsTo,
      this.callback,
      OptionType type,
      {this.negatable,
      bool? splitCommas,
      this.mandatory = false,
      this.hide = false,
      this.aliases = const []})
      : allowed = allowed == null ? null : List.unmodifiable(allowed),
        allowedHelp =
            allowedHelp == null ? null : Map.unmodifiable(allowedHelp),
        type = type,
        // If the user doesn't specify [splitCommas], it defaults to true for
        // multiple options.
        splitCommas = splitCommas ?? type == OptionType.multiple {
    if (name.isEmpty) {
      throw ArgumentError('Name cannot be empty.');
    } else if (name.startsWith('-')) {
      throw ArgumentError('Name $name cannot start with "-".');
    }

    // Ensure name does not contain any invalid characters.
    if (_invalidChars.hasMatch(name)) {
      throw ArgumentError('Name "$name" contains invalid characters.');
    }

    var abbr = this.abbr;
    if (abbr != null) {
      if (abbr.length != 1) {
        throw ArgumentError('Abbreviation must be null or have length 1.');
      } else if (abbr == '-') {
        throw ArgumentError('Abbreviation cannot be "-".');
      }

      if (_invalidChars.hasMatch(abbr)) {
        throw ArgumentError('Abbreviation is an invalid character.');
      }
    }
  }

  /// Returns [value] if non-`null`, otherwise returns the default value for
  /// this option.
  ///
  /// For single-valued options, it will be [defaultsTo] if set or `null`
  /// otherwise. For multiple-valued options, it will be an empty list or a
  /// list containing [defaultsTo] if set.
  dynamic valueOrDefault(value) {
    if (value != null) return value;
    if (isMultiple) return defaultsTo ?? <String>[];
    return defaultsTo;
  }

  @Deprecated('Use valueOrDefault instead.')
  dynamic getOrDefault(value) => valueOrDefault(value);

  static final _invalidChars = RegExp(r'''[ \t\r\n"'\\/]''');
}

/// What kinds of values an option accepts.
class OptionType {
  /// An option that can only be `true` or `false`.
  ///
  /// The presence of the option name itself in the argument list means `true`.
  static const flag = OptionType._('OptionType.flag');

  /// An option that takes a single value.
  ///
  /// Examples:
  ///
  ///     --mode debug
  ///     -mdebug
  ///     --mode=debug
  ///
  /// If the option is passed more than once, the last one wins.
  static const single = OptionType._('OptionType.single');

  /// An option that allows multiple values.
  ///
  /// Example:
  ///
  ///     --output text --output xml
  ///
  /// In the parsed `ArgResults`, a multiple-valued option will always return
  /// a list, even if one or no values were passed.
  static const multiple = OptionType._('OptionType.multiple');

  final String name;

  const OptionType._(this.name);
}
