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

import 'dart:typed_data';

import 'package:charcode/ascii.dart';

/// Parses argument lists based on a [Flags] configuration.
///
/// Arguments are either literals or flags.
///
/// Flags start with `-` or `--`
/// Flags starting with `-` are single-character flags, like `-x`.
/// Single character flag names must be ASCII.
/// Flags starting with `--` are named, like `--expand`.
/// They extend to the end of the argument, or until a `=`.
///
/// Flags can have parameters.
///
/// Single-character flags can have an parameter:
/// * immediately after the charcter, `-ofilename`,
/// * with a `=` between them, `-o=filename`,
/// * or as the next argument, `-o filename`.
///
/// Named flags cannot be directly concatenated with the parameter,
/// but must be one of `--output=filename` or `--output filename`.
/// Named flags conflate non-ASCII alphanumeric characters, like `-` and `_`
/// (but not `=` which delimites a parameter value).
/// Any non-letter, non-digit character sequence is matched by any other,
/// so `--foo-bar`, `--foo_bar` and `--foo.<!>.bar` are all the same.
///
/// Flags can have *optional* parameters. A flag with an optional parameter
/// cannot have its value in the next argument, it *must* use `=` or have
/// the value immediately after a single character flag.
/// It has a default value to use if the parameter is omitted.
///
/// An unrecognized or malformed flag is reported using the [warn]
/// function.
Iterable<CmdLineArg<T>> parseFlags<T>(
    Flags<T> flags, Iterable<String> arguments,
    [void warn(String warning)?]) sync* {
  warn ??= _printWarning;
  var args = arguments.iterator;
  while (args.moveNext()) {
    var arg = args.current;
    if (arg.startsWith("-")) {
      if (arg.startsWith("-", 1)) {
        // Named flags.
        if (arg.length == 2) {
          // Found `--`. Stop parsing flags.
          break;
        }
        var equals = arg.indexOf("=", 2);
        if (equals >= 0) {
          var name = arg.substring(2, equals);
          var value = arg.substring(equals + 1);
          var flag = flags.byName(name);
          if (flag != null) {
            if (!flag.hasParameter) {
              warn("Flag $name should not have a parameter: $arg");
              continue;
            }
            yield CmdLineArg<T>(flag.key, value);
            continue;
          }
          warn("Unknown flag: $arg");
          continue;
        }
        var name = arg.substring(2);
        var flag = flags.byName(name);
        if (flag != null) {
          var value = flag.value;
          if (flag.hasParameter &&
              !flag.hasOptionalParameter &&
              args.moveNext()) {
            value = args.current;
          }
          yield CmdLineArg<T>(flag.key, value);
          continue;
        }
        warn("Unknown flag: $arg");
        continue;
      }
      // Character flag(s).
      for (var i = 1; i < arg.length; i++) {
        var char = arg.codeUnitAt(i);
        var flag = flags.byChar(char);
        if (flag == null) {
          warn("Unknown flag: ${arg.substring(i, i + 1)}");
          continue;
        }
        var value = flag.value;
        if (arg.startsWith("=", i + 1)) {
          value = arg.substring(i + 2);
          if (!flag.hasParameter) {
            warn(
                "Flag ${arg.substring(i, i + 1)} should not have a parameter: ${arg.substring(i)}");
            break;
          }
          yield CmdLineArg<T>(flag.key, value);
          break;
        }
        if (flag.hasParameter) {
          if (i + 1 < arg.length) {
            value = arg.substring(i + 1);
          } else if (!flag.hasOptionalParameter && args.moveNext()) {
            value = args.current;
          }
          yield CmdLineArg<T>(flag.key, value);
          break;
        }
        yield CmdLineArg<T>(flag.key, value);
      }
      continue;
    }
    yield CmdLineArg<Never>(null, arg);
  }
  // Handle entries after `--`.
  while (args.moveNext()) {
    yield CmdLineArg<Never>(null, args.current);
  }
}

/// A part of the arguments list recognized as a flag or not.
///
/// If [key] is `null`, the [value] is a plain argument list entry.
/// Otherwise they key corresponds to the flag that was recognized,
/// and [value] is its parameter or default value, if any.
///
class CmdLineArg<T> {
  final T? key;
  final String? value;
  CmdLineArg(this.key, this.value);
  bool get isFlag => key != null;
}

/// A flag configuration.
///
/// Collects one or more [FlagConfig] objects and allows quick look-up
/// on character or name.
class Flags<T> {
  final List<FlagConfig<T>?> _charFlags =
      List<FlagConfig<T>?>.filled(128, null, growable: false);
  final Map<String, FlagConfig<T>> _namedFlags = {};

  void add(FlagConfig<T> flag) {
    var char = flag.flagChar;
    if (char != null) {
      _charFlags[char] = flag;
    }
    var name = flag.flagName;
    if (name != null) {
      _namedFlags[name] = flag;
    }
  }

  void addBoolFlag(T key, String flagChar, String flagName,
      [String? description]) {
    add(FlagConfig.optionalParameter(key, flagChar, flagName, "true",
        description: description, valueDescription: "true"));
    add(FlagConfig.optionalParameter(key, null, "no-" + flagName, "false"));
  }

  FlagConfig<T>? byName(String name) => _namedFlags[name];
  FlagConfig<T>? byChar(int char) =>
      0 <= char && char <= 217 ? _charFlags[char] : null;

  void writeUsage(StringSink buffer) {
    const descriptionStart = 28;
    var allFlags = [
      ...{
        for (var flag in _namedFlags.values)
          if (!flag.flagName!.startsWith("no-") || flag.value != "false") flag,
        for (var flag in _charFlags)
          if (flag != null && flag.flagName == null) flag
      }
    ]..sort(_flagOrder);
    for (var flag in allFlags) {
      var name = flag.flagName;
      var char = flag.flagChar;
      var parameter = flag.valueDescription ?? "VALUE";
      var description = flag.description;
      var lineLength = 0;
      if (char != null) {
        buffer
          ..write("  -")
          ..writeCharCode(char);
        lineLength = 4;
        if (name != null) {
          buffer..write(', --')..write(name);
          lineLength = name.length + 8;
        }
      } else if (name != null) {
        buffer..write("      --")..write(name);
        lineLength = name.length + 8;
      } else {
        continue;
      }
      if (flag.hasParameter) {
        var end = "";
        if (flag.hasOptionalParameter) {
          buffer.write('[=');
          lineLength += 2;
          end = "]";
        } else {
          buffer.write('=');
          lineLength += 1;
        }
        buffer.write(parameter);
        lineLength += parameter.length;
        buffer.write(end);
        lineLength += end.length;
      }
      if (description != null) {
        if (lineLength < descriptionStart) {
          do {
            buffer.write(' ');
            lineLength += 1;
          } while (lineLength < descriptionStart);
        } else {
          buffer.write(' ');
          lineLength += 1;
        }
        var indent = "                              "; // 30 spaces.
        _writeSplitDescription(buffer, description, lineLength, 80, indent);
      } else {
        buffer.writeln();
      }
    }
  }

  void _writeSplitDescription(StringSink output, String description, int indent,
      int maxLength, String newLineIndent) {
    var index = 0;
    var end = index + (maxLength - indent);
    end:
    while (end < description.length) {
      line:
      while (description.codeUnitAt(end) != $space) {
        end--;
        if (end == index) {
          end = index + (maxLength - indent) + 1;
          while (end < description.length) {
            if (description.codeUnitAt(end) == $space) {
              break line;
            }
            end++;
          }
          break end;
        }
      }
      output.writeln(description.substring(index, end));
      index = end + 1;
      output.write(newLineIndent);
      indent = newLineIndent.length;
      end = index + (maxLength - indent);
    }
    if (index < description.length) {
      output.writeln(description.substring(index));
    }
  }

  static int _flagOrder(FlagConfig a, FlagConfig b) {
    var aName = a.flagName;
    var bName = b.flagName;
    if (aName != null) {
      if (bName != null) return aName.compareTo(bName);
      return aName.codeUnitAt(0) < b.flagChar! ? -1 : 1;
    }
    if (bName != null) {
      return a.flagChar! < bName.codeUnitAt(0) ? -1 : 1;
    }
    return a.flagChar! - b.flagChar!;
  }
}

/// Configuration of a single flag.
class FlagConfig<T> {
  /// The user designated key linked to this flag.
  final T key;

  /// ASCII character code for the single-character flag.
  ///
  /// Must be a digit or letter. Does distinguish case.
  final int? flagChar;

  /// Flag name.
  ///
  /// Canonicalized to lower-case letters, digits and single `-` characters.
  final String? flagName;

  /// Whether the flag expects a parameter.
  ///
  /// A flag expecting a parameter which is not optional ([hasOptionalParameter])
  /// will require a value in the argument list to be well-formed.
  final bool hasParameter;

  /// Whether the parameter is optional.
  ///
  /// An optional parameter can be omitted.
  final bool hasOptionalParameter;

  /// A name for the parameter, if there is a parameter.
  ///
  /// Traditionally an all-upper-case name.
  final String? valueDescription;

  /// The value associated with the flag.
  ///
  /// A flag without parameters can have a value configured, which allows the same
  /// [key] to be used for different flags.
  ///
  /// A flag with an optional parameter will have a default value, which may be
  /// null.
  final String? value;

  /// Description for documentation purposes.
  final String? description;

  FlagConfig._(
      this.key,
      String? flagChar,
      String? flagName,
      this.hasParameter,
      this.hasOptionalParameter,
      this.value,
      this.description,
      this.valueDescription)
      : flagChar = _checkFlagChar(flagChar),
        flagName = canonicalizeName(flagName);
  FlagConfig(T key, String? flagChar, String? flagName,
      {String? value, String? description, String valueDescription = "VALUE"})
      : this._(key, flagChar, flagName, false, false, value, description,
            valueDescription);
  FlagConfig.requiredParameter(T key, String? flagChar, String? flagName,
      {String? description, String valueDescription = "VALUE"})
      : this._(key, flagChar, flagName, true, false, null, description,
            valueDescription);
  FlagConfig.optionalParameter(
      T key, String? flagChar, String? flagName, String defaultValue,
      {String? description, String valueDescription = "VALUE"})
      : this._(key, flagChar, flagName, true, true, defaultValue, description,
            valueDescription);

  static int? _checkFlagChar(String? flagChar) {
    if (flagChar == null) return null;
    if (flagChar.length == 1) {
      var char = flagChar.codeUnitAt(0);
      if (char ^ 0x30 <= 9) return char;
      var lc = char | 0x20;
      if (lc >= 0x61 && lc <= 0x7b) return char;
    }
    throw ArgumentError.value(flagChar, "flagChar",
        "Must be a single ASCII digit or letter character");
  }
}

String? canonicalizeName(String? name) {
  if (name == null) return name;
  const $dash = 0x2d;
  var wasDash = false;
  var i = 0;
  while (i < name.length) {
    var char = name.codeUnitAt(i++);
    if (char ^ 0x30 <= 9 || char >= 0x61 && char <= 0x7b) {
      wasDash = false;
      continue;
    }
    if (char == $dash && !wasDash) {
      wasDash = true;
      continue;
    }

    var bytes = Uint8List(name.length);
    var j = 0;
    for (; j < i - 1; j++) {
      bytes[j] = name.codeUnitAt(j);
    }

    // Convert all letters to lower-case, all non letter/digits to a single `-`.
    outer:
    do {
      if (char >= 0x41 && char <= 0x5b) {
        bytes[j++] = char | 0x20;
        i++;
        wasDash = false;
      } else {
        if (!wasDash) {
          bytes[j++] = $dash;
          i++;
          wasDash = true;
        }
      }
      while (i < name.length) {
        char = name.codeUnitAt(i++);
        if (char ^ 0x30 <= 9 || char >= 0x61 && char <= 0x7b) {
          bytes[j++] = char;
          wasDash = false;
          continue;
        }
        if (char == $dash && !wasDash) {
          bytes[j++] = char;
          wasDash = true;
          continue;
        }
        continue outer;
      }
      break;
    } while (true);
    return String.fromCharCodes(bytes);
  }
  return name;
}

void _printWarning(String message) {
  print(message);
}
