// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:fxtest/fxtest.dart';
import 'package:meta/meta.dart';

/// Helper which pairs positional test name arguments with any trailing `-a`
/// arguments, or, similarly, `-p` arguments with any trailing `-c` arguments.
///
/// Also translates any test name value of "." to the current working directory,
/// since we can safely assume "." will never be an actual test name.
///
/// There is some redudancy in the values passed to [rawArgs] and [testNames]
/// due to details of the `ArgParser`'s API. This stems from the fact that args
/// are all parsed into their respective buckets, but original ordering is lost.
/// Thus, we know all the floating arguments passed (testNames), and which values
/// were passed under a `-a` flag, but not which [testNames] those additional
/// `-a` filters immediately followed. Because of this, we take both the
/// extracted [testNames] and the original raw, unparsed series of CLI arguments,
/// and reverse-engineer what we need.
class TestNamesCollector {
  /// All arguments passed to `fx test`. For example, if the user executed:
  ///
  ///   > `fx test test_one -a filter_one test_two --flag_one --flag_two`
  ///
  /// this value would be:
  ///
  ///   > `[test_one, -a, filter_one, test_two, --flag_one, --flag_two,]`
  ///
  /// If the user executed:
  ///
  ///   > `fx test -p pkg-name -c comp-name`
  ///
  /// this value would unsurprisingly be:
  ///
  ///   > `[-p, pkg-name, -c, comp-name]`
  final List<String> rawArgs;

  /// Extracted testNames from the set of arguments passed to `fx test`. For
  /// example, if the user executed:
  ///
  ///   > `fx test test_one -a filter_one test_two --flag_one --flag_two`
  ///
  /// this value would be:
  ///
  ///   > `[test_one, test_two]`
  ///
  /// If the user executed:
  ///
  ///   > `fx test test_one -p pkg-name -c comp-name`
  ///
  /// this value would be:
  ///
  ///   > `[test_one]`
  final List<String> testNames;

  TestNamesCollector({
    /// The entire string of arguments passed to `fx test`.
    @required List<String> rawArgs,

    /// The extracted test names from all arguments passed to `fx test`.
    @required List<String> rawTestNames,
    FuchsiaLocator fuchsiaLocator,
  })  : testNames = TestNamesCollector._processTestList(
          rawTestNames,
          fuchsiaLocator ?? FuchsiaLocator.shared,
        ),
        rawArgs = TestNamesCollector._processRawArgs(
          rawArgs,
          fuchsiaLocator ?? FuchsiaLocator.shared,
        );

  /// Loops over a combination of the original, raw list of arguments, and the
  /// parsed arguments, to determine which positional arguments are modified by
  /// a trailing `--a|-a` flag. For example,
  ///
  /// ```
  /// test_one -a filter_one test_two -a filter_two -a filter_two_b test_three
  /// ```
  ///
  /// Should be parsed into:
  ///
  /// ```
  /// [
  ///   [<MatchableTestName "test_one">, <MatchableTestName "filter_one">],
  ///   [<MatchableTestName "test_two>, <MatchableTestName "filter_two">, <MatchableTestName "filter_two_b">],
  ///   [<MatchableTestName "test_three">]
  /// ]
  /// ```
  List<List<MatchableTestName>> collect() {
    List<List<MatchableTestName>> groupedTestFilters = [];
    var seenRootNames = <String>{};
    var args = _ListEmitter<String>(rawArgs);

    while (args.hasMore()) {
      var arg = args.take();
      if (seenRootNames.contains(arg)) {
        continue;
      }
      _ArgumentsProgress argsProgress;
      if (testNames.contains(arg)) {
        seenRootNames.add(arg);
        groupedTestFilters.add([MatchableTestName.unrestricted(arg)]);
        argsProgress = _takeAndFilters(
          args,
          testNames,
        );
      } else if (['--package', '-p'].contains(arg)) {
        // Break out if we're at the end and had a dangling `-p` flag.
        if (!args.hasMore()) break;

        var nextArg = args.take();
        groupedTestFilters.add([MatchableTestName.packageName(nextArg)]);
        argsProgress = _takeComponentFilters(
          args,
          testNames,
        );
      } else if (['--component', '-c'].contains(arg)) {
        // Break out if we're at the end and had a dangling `-c` flag.
        if (!args.hasMore()) break;

        var nextArg = args.take();
        groupedTestFilters.add([MatchableTestName.componentName(nextArg)]);
      }
      if (argsProgress != null) {
        if (argsProgress.additionalFilters.isNotEmpty) {
          groupedTestFilters[groupedTestFilters.length - 1]
              .addAll(argsProgress.additionalFilters);
        }
        args = argsProgress.args;
      }
    }
    if (groupedTestFilters.isEmpty) {
      groupedTestFilters.add([MatchableTestName.empty()]);
    }
    return groupedTestFilters;
  }

  _ArgumentsProgress _takeComponentFilters(
    _ListEmitter<String> args,
    List<String> testNames,
  ) {
    final additionalFilters = <MatchableTestName>[];

    // Stop 1 item early because a trailing `-c` flag is definitionally
    // not followed by another token
    while (args.hasNMore(2)) {
      var arg = args.peek();
      if (['--component', '-c'].contains(arg)) {
        // Confirm our peek
        args.take();
        var nextArg = args.take();
        additionalFilters.add(MatchableTestName.componentName(nextArg));
      } else {
        break;
      }
    }
    return _ArgumentsProgress(args, additionalFilters);
  }

  _ArgumentsProgress _takeAndFilters(
    _ListEmitter<String> args,
    List<String> testNames,
  ) {
    final additionalFilters = <MatchableTestName>[];

    // Stop 1 item early because a trailing `-a` flag is definitionally
    // not followed by another token
    while (args.hasNMore(2)) {
      var arg = args.peek();
      if (['--all', '-a'].contains(arg)) {
        // Confirm our peek
        args.take();
        var nextFilter = args.take();
        additionalFilters.addAll(
          nextFilter
              .split(',')
              .map((testName) => MatchableTestName.unrestricted(testName))
              .toList(),
        );
      } else {
        break;
      }
    }
    return _ArgumentsProgress(args, additionalFilters);
  }

  static List<String> _processTestList(
    List<String> testList,
    FuchsiaLocator fuchsiaLocator,
  ) {
    // Replace a test name that is merely "." with the actual current directory
    // Use a set-to-list maneuver to remove duplicates
    return {
      for (var testName in testList)
        testName == cwdToken ? fuchsiaLocator.relativeCwd : testName
    }.toList();
  }

  static List<String> _processRawArgs(
    List<String> rawArgs,
    FuchsiaLocator fuchsiaLocator,
  ) {
    // Replace a test name that is merely "." with the actual current directory
    // Use a set-to-list maneuver to remove duplicates
    return [
      for (var arg in rawArgs)
        arg == cwdToken ? fuchsiaLocator.relativeCwd : arg
    ];
  }
}

/// Helper that tracks progress through the positionally-aware parsing of
/// raw arguments.
class _ArgumentsProgress {
  final _ListEmitter<String> args;
  final List<MatchableTestName> additionalFilters;
  _ArgumentsProgress(this.args, this.additionalFilters);
}

class _ListEmitter<T> {
  final List<T> _list;
  int _counter = 0;
  _ListEmitter(this._list);

  /// Look at the next item in the list without advancing the marker.
  T peek() => _list.length > _counter ? _list[_counter] : null;

  /// Look at the next item in the list and advance the marker.
  T take() {
    if (_counter == _list.length) return null;
    _counter += 1;
    return _list[_counter - 1];
  }

  bool hasMore() => hasNMore(1);
  bool hasNMore(int numberMore) => _list.length - _counter >= numberMore;
}

enum MatchType {
  /// Default rule which can match against any portion of a [TestDefinition].
  unrestricted,

  /// Specialized rule which indicates only matching against package names.
  packageName,

  /// Specialized rule which indicates only matching against component names.
  componentName,
}

/// Container for a [String] used to match against different parts of test names
/// with an additional [MatchType] attribute which optionally specifies
/// limitations on parts of a [TestDefinition] eligible for matching.
class MatchableTestName {
  final String testNameToken;
  final MatchType matchType;

  /// Generic constructor which accepts all paramters. Not preferred for
  /// external use.
  MatchableTestName._(this.testNameToken, this.matchType);

  /// Helper constructor for unrestricted matchers.
  factory MatchableTestName.unrestricted(String testNameToken) =>
      MatchableTestName._(testNameToken, MatchType.unrestricted);

  /// Helper constructor for package-name matchers.
  factory MatchableTestName.packageName(String testNameToken) =>
      MatchableTestName._(testNameToken, MatchType.packageName);

  /// Helper constructor for component-name matchers.
  factory MatchableTestName.componentName(String testNameToken) =>
      MatchableTestName._(testNameToken, MatchType.componentName);

  /// Helper constructor for when there are zero test name tokens whatsoever.
  factory MatchableTestName.empty() =>
      MatchableTestName._(null, MatchType.unrestricted);

  @override
  bool operator ==(dynamic other) {
    return identical(this, other) ||
        (other is MatchableTestName &&
            runtimeType == other.runtimeType &&
            testNameToken == other.testNameToken &&
            matchType == other.matchType);
  }

  @override
  int get hashCode => testNameToken.hashCode ^ matchType.hashCode;

  @override
  String toString() =>
      '<MatchableTestName ${matchType.toString().split('.')[1]}::"$testNameToken" />';
}
