// 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.

import 'dart:collection';
import 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';
import 'package:path/path.dart' as path;

import 'configuration.dart';
import 'path.dart';
import 'repository.dart';
import 'test_configurations.dart';
import 'utils.dart';

const _defaultTestSelectors = [
  'samples_2',
  'standalone_2',
  'corelib_2',
  'language_2',
  'vm',
  'benchmark_smoke',
  'utils',
  'lib_2',
  'analyze_library',
  'service_2',
  'kernel',
  'observatory_ui_2',
  'ffi_2'
];

extension _IntOption on ArgParser {
  void addIntegerOption(String name,
      {String abbr,
      String help,
      String valueHelp,
      Iterable<String> allowed,
      Map<String, String> allowedHelp,
      String defaultsTo,
      bool mandatory = false,
      bool hide = false,
      List<String> aliases = const []}) {
    addOption(name,
        abbr: abbr,
        help: help,
        valueHelp: valueHelp,
        allowed: allowed,
        allowedHelp: allowedHelp,
        defaultsTo: defaultsTo, callback: (value) {
      if (value != null) {
        int.tryParse(value) ??
            _fail('Integer value expected for option "--$name".');
      }
    }, mandatory: mandatory, hide: hide, aliases: aliases);
  }
}

/// Parses command line arguments and produces a test runner configuration.
class OptionsParser {
  /// Allows tests to specify a custom test matrix.
  final String _testMatrixFile;

  OptionsParser([this._testMatrixFile = 'tools/bots/test_matrix.json']);

  static final ArgParser parser = ArgParser()
    ..addMultiOption('mode',
        abbr: 'm',
        allowed: ['all', ...Mode.names],
        help: 'Mode in which to run the tests.')
    ..addMultiOption('compiler',
        abbr: 'c',
        allowed: Compiler.names,
        help: '''How the Dart code should be compiled or statically processed.
none:                 Do not compile the Dart code.
dart2js:              Compile to JavaScript using dart2js.
dart2analyzer:        Perform static analysis on Dart code using the analyzer.
compare_analyzer_cfe: Compare analyzer and common front end representations.
dartdevc:             Compile to JavaScript using dartdevc.
dartdevk:             Compile to JavaScript using dartdevc (same as dartdevc).
app_jitk:             Compile the Dart code into Kernel and then into an app
                      snapshot.
dartk:                Compile the Dart code into Kernel before running test.
dartkp:               Compile the Dart code into Kernel and then Kernel into
                      AOT snapshot before running the test.
spec_parser:          Parse Dart code using the specification parser.
fasta:                Compile using CFE for errors, but do not run.
''')
    ..addMultiOption('runtime',
        abbr: 'r',
        allowed: Runtime.names,
        help: '''Where the tests should be run.
vm:               Run Dart code on the standalone Dart VM.
dart_precompiled: Run a precompiled snapshot on the VM without a JIT.
d8:               Run JavaScript from the command line using v8.
jsshell:          Run JavaScript from the command line using Firefox js-shell.

firefox:
chrome:
safari:
ie9:
ie10:
ie11:
chromeOnAndroid:  Run JavaScript in the specified browser.

none:             No runtime, compile only.''')
    ..addMultiOption('arch',
        abbr: 'a',
        allowed: ['all', ...Architecture.names],
        defaultsTo: [Architecture.x64.name],
        hide: true,
        help: '''The architecture to run tests for.

Allowed values are:
all
ia32, x64
arm, arm64, simarm, simarm64, arm_x64
riscv32, riscv64, simriscv32, simriscv64''')
    ..addOption('system',
        abbr: 's',
        allowed: ['all', ...System.names],
        defaultsTo: Platform.operatingSystem,
        hide: true,
        help: 'The operating system to run tests on.')
    ..addMultiOption('sanitizer',
        allowed: ['all', ...Sanitizer.names],
        defaultsTo: [Sanitizer.none.name],
        help: 'Sanitizer in which to run the tests.')
    ..addMultiOption('named-configuration',
        abbr: 'n',
        aliases: ['named_configuration'],
        hide: true,
        help: '''The named test configuration that supplies the values for all
test options, specifying how tests should be run.''')
    ..addFlag('build',
        help: 'Build the necessary targets to test this configuration')
    // TODO(sigmund): rename flag once we migrate all dart2js bots to the test
    // matrix.
    ..addFlag('host-checked',
        aliases: ['host_checked'],
        hide: true,
        help: 'Run compiler with assertions enabled.')
    ..addFlag('minified',
        hide: true, help: 'Enable minification in the compiler.')
    ..addFlag('csp',
        hide: true,
        help: 'Run tests under Content Security Policy restrictions.')
    ..addFlag('fast-tests',
        aliases: ['fast_tests'],
        hide: true,
        help: 'Only run tests that are not marked `Slow` or `Timeout`.')
    ..addFlag('enable-asserts',
        aliases: ['enable_asserts'],
        help: 'Pass the --enable-asserts flag to dart2js or to the vm.')
    ..addFlag('use-cfe',
        aliases: ['use_cfe'],
        hide: true,
        help: 'Pass the --use-cfe flag to analyzer')
    ..addFlag('analyzer-use-fasta-parser',
        aliases: ['analyzer_use_fasta_parser'],
        hide: true,
        help: 'Pass the --use-fasta-parser flag to analyzer')
    ..addFlag('hot-reload', hide: true, help: 'Run hot reload stress tests.')
    ..addFlag('hot-reload-rollback',
        hide: true, help: 'Run hot reload rollback stress tests.')
    ..addFlag('use-blobs',
        aliases: ['use_blobs'],
        hide: true,
        help: 'Use mmap instead of shared libraries for precompilation.')
    ..addFlag(
      'use-elf',
      aliases: ['use_elf'],
      hide: true,
      help: 'Directly generate an ELF shared libraries for precompilation.',
    )
    ..addFlag('use-qemu',
        aliases: ['use_qemu'],
        hide: true,
        help: 'Use qemu to test arm32 on x64 host machines.')
    ..addFlag('keep-generated-files',
        abbr: 'k', hide: true, help: 'Keep any generated files.')
    ..addIntegerOption('timeout', abbr: 't', help: 'Timeout in seconds.')
    ..addOption('progress',
        abbr: 'p',
        allowed: Progress.names,
        defaultsTo: Progress.compact.name,
        help: '''Progress indication mode.

Allowed values are:
compact, color, line, verbose, silent, status, buildbot''')
    ..addOption('step-name',
        aliases: ['step_name'],
        hide: true,
        help: 'Step name for use by -pbuildbot.')
    ..addFlag('report',
        hide: true,
        help: 'Print a summary report of the number of tests, by expectation.')
    ..addFlag('report-failures',
        aliases: ['report_failures'],
        hide: true,
        help: 'Print a summary of the tests that failed.')
    ..addOption('tasks',
        abbr: 'j',
        defaultsTo: Platform.numberOfProcessors.toString(),
        help: 'The number of parallel tasks to run.')
    ..addIntegerOption('shards',
        defaultsTo: '1',
        hide: true,
        help: 'The number of instances that the tests will be sharded over.')
    ..addIntegerOption('shard',
        defaultsTo: '1',
        hide: true,
        help: 'The index of this instance when running in sharded mode.')
    ..addFlag('help', abbr: 'h', help: 'Print list of options.')
    ..addIntegerOption('repeat',
        defaultsTo: '1', help: 'How many times each test is run')
    ..addFlag('verbose', abbr: 'v', help: 'Verbose output.')
    ..addFlag('verify-ir',
        aliases: ['verify_ir'], hide: true, help: 'Verify kernel IR.')
    ..addFlag('no-tree-shake',
        aliases: ['no_tree_shake'],
        hide: true,
        help: 'Disable kernel IR tree shaking.')
    ..addFlag('list', help: 'List tests only, do not run them.')
    ..addFlag('find-configurations',
        aliases: ['find_configurations'], help: 'Find matching configurations.')
    ..addFlag('list-configurations',
        aliases: ['list_configurations'],
        help: 'Output list of configurations.')
    ..addFlag('list-status-files',
        aliases: ['list_status_files'],
        hide: true,
        help: 'List status files for test suites. Do not run any test suites.')
    ..addFlag('clean-exit',
        aliases: ['clean_exit'],
        hide: true,
        help: 'Exit 0 if tests ran and results were output.')
    ..addFlag('silent-failures',
        aliases: ['silent_failures'],
        hide: true,
        help: "Don't complain about failing tests. This is useful when in "
            "combination with --write-results.")
    ..addFlag('report-in-json',
        aliases: ['report_in_json'],
        hide: true,
        help: 'When listing with --list, output result summary in JSON.')
    ..addFlag('time', help: 'Print timing information after running tests.')
    ..addOption('dart', hide: true, help: 'Path to dart executable.')
    ..addOption('gen-snapshot',
        aliases: ['gen_snapshot'],
        hide: true,
        help: 'Path to gen_snapshot executable.')
    ..addOption('firefox',
        hide: true, help: 'Path to firefox browser executable.')
    ..addOption('chrome',
        hide: true, help: 'Path to chrome browser executable.')
    ..addOption('safari',
        hide: true, help: 'Path to safari browser executable.')
    ..addFlag('use-sdk',
        aliases: ['use_sdk'], help: 'Use compiler or runtime from the SDK.')
    ..addOption('nnbd',
        allowed: NnbdMode.names,
        defaultsTo: NnbdMode.legacy.name,
        help: '''Which set of non-nullable type features to use.

Allowed values are: legacy, weak, strong''')
    // TODO(rnystrom): This does not appear to be used. Remove?
    ..addOption('build-directory',
        aliases: ['build_directory'],
        help: 'The name of the build directory, where products are placed.',
        hide: true)
    ..addOption('output-directory',
        aliases: ['output_directory'],
        defaultsTo: "logs",
        hide: true,
        help: 'The name of the output directory for storing log files.')
    ..addFlag('no-batch',
        aliases: ['no_batch'],
        hide: true,
        help: "Don't run tests in batch mode.")
    ..addFlag('write-debug-log',
        aliases: ['write_debug_log'],
        hide: true,
        help: "Don't write debug messages to stdout but rather to a logfile.")
    ..addFlag('write-results',
        aliases: ['write_results'],
        hide: true,
        help: 'Write results to a "${TestUtils.resultsFileName}" json file '
            'located at the debug-output-directory.')
    ..addFlag('write-logs',
        aliases: ['write_logs'],
        hide: true,
        help: 'Write failing test stdout and stderr to to the '
            '"${TestUtils.logsFileName}" file')
    ..addFlag('reset-browser-configuration',
        aliases: ['reset_browser_configuration'],
        hide: true,
        help: '''Browser specific reset of configuration.

Warning: Using this option may remove your bookmarks and other
settings.''')
    ..addFlag('copy-coredumps',
        aliases: ['copy_coredumps'],
        hide: true,
        help: 'Copy core dumps to "/tmp" when an unexpected crash occurs.')
    ..addFlag('rr',
        hide: true,
        help: '''Run VM tests under rr and save traces from crashes''')
    ..addOption('local-ip',
        aliases: ['local_ip'],
        hide: true,
        help: '''IP address the HTTP servers should listen on. This address is
also used for browsers to connect to.''',
        defaultsTo: '127.0.0.1')
    ..addIntegerOption('test-server-port',
        aliases: ['test_server_port'],
        hide: true,
        defaultsTo: '0',
        help: 'Port for test http server.')
    ..addIntegerOption('test-server-cross-origin-port',
        aliases: ['test_server_cross_origin_port'],
        hide: true,
        help: 'Port for test http server cross origin.',
        defaultsTo: '0')
    ..addIntegerOption('test-driver-error-port',
        aliases: ['test_driver_error_port'],
        hide: true,
        help: 'Port for http test driver server errors.',
        defaultsTo: '0')
    ..addOption('test-list',
        aliases: ['test_list'],
        hide: true,
        help: 'File containing a list of tests to be executed.')
    ..addOption('tests',
        help: 'A newline separated list of tests to be executed.')
    ..addOption('builder-tag',
        aliases: ['builder_tag'],
        help:
            '''Machine specific options that is not captured by the regular test
options. Used to be able to make sane updates to the status files.''',
        hide: true)
    ..addMultiOption('vm-options',
        aliases: ['vm_options'],
        hide: true,
        help: 'Extra options to send to the VM when running.')
    ..addMultiOption('dart2js-options',
        aliases: ['dart2js_options'],
        hide: true,
        help: 'Extra options for dart2js compilation step.')
    ..addMultiOption('shared-options',
        aliases: ['shared_options'], hide: true, help: 'Extra shared options.')
    ..addMultiOption('enable-experiment',
        aliases: ['experiments', 'enable_experiment'],
        help: 'Experiment flags to enable.')
    ..addOption('babel',
        help: '''Transforms dart2js output with Babel. The value must be
Babel options JSON.''',
        hide: true)
    ..addOption('suite-dir',
        aliases: ['suite_dir'],
        hide: true,
        help: 'Additional directory to add to the testing matrix.')
    ..addOption('packages',
        hide: true, help: 'The package spec file to use for testing.')
    ..addOption('exclude-suite',
        aliases: ['exclude_suite'],
        hide: true,
        help:
            '''Exclude suites from default selector, only works when no selector
has been specified on the command line.''')
    ..addFlag('print-passing-stdout',
        aliases: ['print_passing_stdout'],
        hide: true,
        help: 'Print the stdout of passing, as well as failing, tests.')
    ..addOption('service-response-sizes-directory',
        aliases: ['service_response_sizes_directory'],
        hide: true,
        help:
            'Log VM service response size CSV files in the provided directory');

  /// For printing out reproducing command lines, we don't want to add these
  /// options.
  static const _denylistedOptions = {
    'build',
    'build-directory',
    'chrome',
    'clean-exit',
    'copy-coredumps',
    'dart',
    'debug-output-directory',
    'drt',
    'exclude-suite',
    'firefox',
    'local-ip',
    'output-directory',
    'progress',
    'repeat',
    'report',
    'report-failures',
    'reset-browser-configuration',
    'safari',
    'shard',
    'shards',
    'silent-failures',
    'step-name',
    'tasks',
    'tests',
    'time',
    'verbose',
    'write-debug-log',
    'write-logs',
    'write-results',
  };

  /// The set of objects which the named configuration should imply.
  static const _namedConfigurationOptions = {
    'system',
    'arch',
    'mode',
    'compiler',
    'runtime',
    'timeout',
    'nnbd',
    'sanitizer',
    'enable-asserts',
    'use-cfe',
    'analyzer-use-fasta-parser',
    'use-elf',
    'use-sdk',
    'hot-reload',
    'hot-reload-rollback',
    'host-checked',
    'csp',
    'minified',
    'vm-options',
    'dart2js_options',
    'experiments',
    'babel',
    'builder-tag',
    'use-qemu'
  };

  /// Parses a list of strings as test options.
  ///
  /// Returns a list of configurations in which to run the tests.
  /// Configurations are maps mapping from option keys to values. When
  /// encountering the first non-option string, the rest of the arguments are
  /// stored in the returned Map under the 'rest' key.
  List<TestConfiguration> parse(List<String> arguments) {
    ArgResults results;
    try {
      results = parser.parse(arguments);
    } on FormatException catch (error) {
      _fail(error.message);
    }
    if (results['help'] as bool) {
      _printHelp(verbose: results['verbose'] as bool);
      return const [];
    }
    var options = {for (var option in results.options) option: results[option]};

    if (options['find-configurations'] as bool) {
      findConfigurations(options);
      return const [];
    }

    if (options['list-configurations'] as bool) {
      listConfigurations(options);
      return const [];
    }

    // If a named configuration was specified ensure no other options, which are
    // implied by the named configuration, were specified.
    if (options['named-configuration'] is String) {
      for (var optionName in _namedConfigurationOptions) {
        if (results.wasParsed(optionName)) {
          var namedConfig = options['named-configuration'];
          _fail("Can't pass '--$optionName' since it is determined by the "
              "named configuration '$namedConfig'.");
        }
      }
    }

    var allSuiteDirectories = [
      ...testSuiteDirectories,
      "tests/co19",
      "tests/co19_2",
    ];

    var selectors = <String>[];
    for (var selector in results.rest) {
      // Allow passing in the full relative path to a test or directory and
      // infer the selector from it. This lets users use tab completion on
      // the command line.
      for (var suiteDirectory in allSuiteDirectories) {
        var path = suiteDirectory.toString();
        if (selector.startsWith("$path/") || selector.startsWith("$path\\")) {
          selector = selector.substring(path.lastIndexOf("/") + 1);

          // Remove the `src/` subdirectories from the co19 and co19_2
          // directories that do not appear in the test names.
          if (selector.startsWith("co19")) {
            selector = selector.replaceFirst(RegExp("src[/\]"), "");
          }
          break;
        }
      }

      // If they tab complete to a single test, ignore the ".dart".
      if (selector.endsWith(".dart")) {
        selector = selector.substring(0, selector.length - 5);
      }

      selectors.add(selector);
    }
    options['selectors'] = selectors;

    // Fetch list of tests to run, if option is present.
    var testList = options['test_list'];
    if (testList is String) {
      options['test-list-contents'] = File(testList).readAsLinesSync();
    }

    var tests = options['tests'];
    if (tests is String) {
      if (options.containsKey('test-list-contents')) {
        _fail('--tests and --test-list cannot be used together');
      }
      options['test-list-contents'] = LineSplitter.split(tests).toList();
    }

    return _createConfigurations(options);
  }

  /// Given a set of parsed option values, returns the list of command line
  /// arguments that would reproduce that configuration.
  List<String> _reproducingCommand(
      Map<String, dynamic> data, bool usingNamedConfiguration) {
    var arguments = <String>[];

    for (var option in parser.options.values) {
      var name = option.name;
      if (!data.containsKey(name) ||
          _denylistedOptions.contains(name) ||
          (usingNamedConfiguration &&
              _namedConfigurationOptions.contains(name))) {
        continue;
      }

      var value = data[name];
      if (data[name] == option.defaultsTo ||
          (name == 'packages' &&
              value ==
                  Repository.uri
                      .resolve('.dart_tool/package_config.json')
                      .toFilePath())) {
        continue;
      }

      if (option.abbr != null) {
        arguments.add('-${option.abbr}');
      } else {
        arguments.add('--${option.name}');
      }
      if (value is String) {
        arguments.add(value);
      } else if (value is List<String>) {
        arguments.add(value.join(','));
      }
    }

    return arguments;
  }

  List<TestConfiguration> _createConfigurations(
      Map<String, dynamic> configuration) {
    var selectors = _expandSelectors(configuration);

    // Put observatory_ui in a configuration with its own packages override.
    // Only one value in the configuration map is mutable:
    if (selectors.containsKey('observatory_ui')) {
      if (selectors.length == 1) {
        configuration['packages'] = Repository.uri
            .resolve('.dart_tool/package_config.json')
            .toFilePath();
      } else {
        // Make a new configuration whose selectors map only contains
        // observatory_ui, and remove observatory_ui from the original
        // selectors. The only mutable value in the map is the selectors, so a
        // shallow copy is safe.
        var observatoryConfiguration = Map<String, dynamic>.from(configuration);
        var observatorySelectors = {
          'observatory_ui': selectors['observatory_ui']
        };
        selectors.remove('observatory_ui');

        // Set the packages flag.
        observatoryConfiguration['packages'] = Repository.uri
            .resolve('.dart_tool/package_config.json')
            .toFilePath();

        return [
          ..._expandConfigurations(configuration, selectors),
          ..._expandConfigurations(
              observatoryConfiguration, observatorySelectors)
        ];
      }
    }

    return _expandConfigurations(configuration, selectors);
  }

  /// Recursively expands a configuration with multiple values per key into a
  /// list of configurations with exactly one value per key.
  List<TestConfiguration> _expandConfigurations(
      Map<String, dynamic> data, Map<String, RegExp> selectors) {
    var result = <TestConfiguration>[];

    // Handles a string option containing a space-separated list of words.
    listOption(String name) {
      var value = data[name] as List<String>;
      return value
          .expand((element) => element
              .split(" ")
              .map((s) => s.trim())
              .where((s) => s.isNotEmpty))
          .toList();
    }

    var dart2jsOptions = listOption("dart2js-options");
    var vmOptions = listOption("vm-options");
    var sharedOptions = listOption("shared-options");
    var experiments = data["enable-experiment"] as List<String>;

    // JSON reporting implies listing and reporting.
    if (data['report-in-json'] as bool) {
      data['list'] = true;
      data['report'] = true;
    }

    // Use verbose progress indication for verbose output unless buildbot
    // progress indication is requested.
    if ((data['verbose'] as bool) &&
        (data['progress'] as String) != 'buildbot') {
      data['progress'] = 'verbose';
    }

    var systemName = data["system"] as String;
    if (systemName == "all") {
      _fail("Can only use '--system=all' with '--find-configurations'.");
    }
    var system = System.find(systemName);
    var runtimes = [...(data["runtime"] as List<String>).map(Runtime.find)];
    var compilers = [...(data["compiler"] as List<String>).map(Compiler.find)];

    // Pick default compilers or runtimes if only one or the other is provided.
    if (runtimes.isEmpty) {
      if (compilers.isEmpty) {
        runtimes = [Runtime.vm];
        compilers = [Compiler.dartk];
      } else {
        // Pick a runtime for each compiler.
        runtimes.addAll(compilers.map((compiler) => compiler.defaultRuntime));
      }
    } else if (compilers.isEmpty) {
      // Pick a compiler for each runtime.
      compilers.addAll(runtimes.map((runtime) => runtime.defaultCompiler));
    }

    var progress = Progress.find(data["progress"] as String);
    var nnbdMode = NnbdMode.find(data["nnbd"] as String);

    void addConfiguration(Configuration innerConfiguration,
        [String namedConfiguration]) {
      var configuration = TestConfiguration(
          configuration: innerConfiguration,
          progress: progress,
          selectors: selectors,
          build: data["build"] as bool,
          testList: data["test-list-contents"] as List<String>,
          repeat: int.parse(data["repeat"] as String),
          batch: !(data["no-batch"] as bool),
          copyCoreDumps: data["copy-coredumps"] as bool,
          rr: data["rr"] as bool,
          isVerbose: data["verbose"] as bool,
          listTests: data["list"] as bool,
          listStatusFiles: data["list-status-files"] as bool,
          cleanExit: data["clean-exit"] as bool,
          silentFailures: data["silent-failures"] as bool,
          printTiming: data["time"] as bool,
          printReport: data["report"] as bool,
          reportFailures: data["report-failures"] as bool,
          reportInJson: data["report-in-json"] as bool,
          resetBrowser: data["reset-browser-configuration"] as bool,
          writeDebugLog: data["write-debug-log"] as bool,
          writeResults: data["write-results"] as bool,
          writeLogs: data["write-logs"] as bool,
          drtPath: data["drt"] as String,
          chromePath: data["chrome"] as String,
          safariPath: data["safari"] as String,
          firefoxPath: data["firefox"] as String,
          dartPath: data["dart"] as String,
          dartPrecompiledPath: data["dart-precompiled"] as String,
          genSnapshotPath: data["gen-snapshot"] as String,
          keepGeneratedFiles: data["keep-generated-files"] as bool,
          taskCount: int.parse(data["tasks"] as String),
          shardCount: int.parse(data["shards"] as String),
          shard: int.parse(data["shard"] as String),
          stepName: data["step-name"] as String,
          testServerPort: int.parse(data['test-server-port'] as String),
          testServerCrossOriginPort:
              int.parse(data['test-server-cross-origin-port'] as String),
          testDriverErrorPort:
              int.parse(data['test-driver-error-port'] as String),
          localIP: data["local-ip"] as String,
          sharedOptions: <String>[
            ...sharedOptions,
            "-Dtest_runner.configuration=${innerConfiguration.name}"
          ],
          packages: data["packages"] as String,
          serviceResponseSizesDirectory:
              data['service-response-sizes-directory'] as String,
          suiteDirectory: data["suite-dir"] as String,
          outputDirectory: data["output-directory"] as String,
          reproducingArguments:
              _reproducingCommand(data, namedConfiguration != null),
          fastTestsOnly: data["fast-tests"] as bool,
          printPassingStdout: data["print-passing-stdout"] as bool);

      if (configuration.validate()) {
        result.add(configuration);
      } else if (namedConfiguration != null) {
        _fail('The named configuration "$namedConfiguration" is invalid.');
      }
    }

    var namedConfigurations = data["named-configuration"] as List<String>;
    if (namedConfigurations.isNotEmpty) {
      var testMatrix = TestMatrix.fromPath(_testMatrixFile);
      for (var namedConfiguration in namedConfigurations) {
        var configuration = testMatrix.configurations.singleWhere(
            (c) => c.name == namedConfiguration,
            orElse: () => null);
        if (configuration == null) {
          var names = testMatrix.configurations
              .map((configuration) => configuration.name)
              .toList()
            ..sort();
          _fail('The named configuration "$namedConfiguration" does not exist.'
              ' The following configurations are available:\n'
              '  * ${names.join('\n  * ')}');
        }
        addConfiguration(configuration, namedConfiguration);
      }
      return result;
    }

    var modes = data['mode'] as List<String>;
    if (modes.contains('all')) {
      modes = Mode.names;
    }
    // Expand runtimes.
    var configurationNumber = 1;
    for (var runtime in runtimes) {
      // Expand architectures.
      var architectures = data["arch"] as List<String>;
      if (architectures.contains("all")) {
        architectures = [
          "ia32",
          "x64",
          "x64c",
          "simarm",
          "simarm64",
          "simarm64c",
          "simriscv32",
          "simriscv64"
        ];
      }

      for (var architectureName in architectures) {
        var architecture = Architecture.find(architectureName);

        // Expand compilers.
        for (var compiler in compilers) {
          // Expand modes.
          for (var modeName
              in modes.isEmpty ? [compiler.defaultMode.name] : modes) {
            var mode = Mode.find(modeName);
            // Expand sanitizers.
            var sanitizers = data["sanitizer"] as List<String>;
            if (sanitizers.contains("all")) {
              sanitizers = Sanitizer.names;
            }
            for (var sanitizerName in sanitizers) {
              var sanitizer = Sanitizer.find(sanitizerName);
              var timeout = data["timeout"] != null
                  ? int.parse(data["timeout"] as String)
                  : null;
              var configuration = Configuration(
                  "custom-configuration-${configurationNumber++}",
                  architecture,
                  compiler,
                  mode,
                  runtime,
                  system,
                  nnbdMode: nnbdMode,
                  sanitizer: sanitizer,
                  timeout: timeout,
                  enableAsserts: data['enable-asserts'] as bool,
                  useAnalyzerCfe: data["use-cfe"] as bool,
                  useAnalyzerFastaParser:
                      data["analyzer-use-fasta-parser"] as bool,
                  useElf: data["use-elf"] as bool,
                  useSdk: data["use-sdk"] as bool,
                  useHotReload: data["hot-reload"] as bool,
                  useHotReloadRollback: data["hot-reload-rollback"] as bool,
                  isHostChecked: data["host-checked"] as bool,
                  isCsp: data["csp"] as bool,
                  isMinified: data["minified"] as bool,
                  vmOptions: vmOptions,
                  dart2jsOptions: dart2jsOptions,
                  experiments: experiments,
                  babel: data['babel'] as String,
                  builderTag: data["builder-tag"] as String,
                  useQemu: data["use-qemu"] as bool);
              addConfiguration(configuration);
            }
          }
        }
      }
    }
    return result;
  }

  /// Expands the test selectors into a suite name and a simple regular
  /// expression to be used on the full path of a test file in that test suite.
  ///
  /// If no selectors are explicitly given, uses the default suite patterns.
  Map<String, RegExp> _expandSelectors(Map<String, dynamic> configuration) {
    var selectors = configuration['selectors'];

    if (selectors == null || (selectors as List).isEmpty) {
      if (configuration['suite-dir'] != null) {
        var suitePath = Path(configuration['suite-dir'] as String);
        selectors = [suitePath.filename];
      } else if (configuration['test-list-contents'] != null) {
        selectors = (configuration['test-list-contents'] as List<String>)
            .map((t) => t.split('/').first)
            .toSet()
            .toList();
      } else {
        selectors = _defaultTestSelectors.toList();
      }

      var excludeSuites = configuration['exclude-suite'] != null
          ? (configuration['exclude-suite'] as String).split(',')
          : [];
      for (var exclude in excludeSuites) {
        if ((selectors as List).contains(exclude)) {
          selectors.remove(exclude);
        } else {
          print("Warning: default selectors does not contain $exclude");
        }
      }
    }

    var selectorMap = <String, RegExp>{};
    for (var i = 0; i < (selectors as List).length; i++) {
      var pattern = selectors[i] as String;
      var suite = pattern;
      var slashLocation = pattern.indexOf('/');
      if (slashLocation != -1) {
        suite = pattern.substring(0, slashLocation);
        pattern = pattern.substring(slashLocation + 1);
        pattern = pattern.replaceAll('*', '.*');
      } else {
        pattern = ".?";
      }
      if (selectorMap.containsKey(suite)) {
        _fail("Error: '$suite/$pattern'.  Only one test selection"
            " pattern is allowed to start with '$suite/'");
      }
      selectorMap[suite] = RegExp(pattern);
    }

    return selectorMap;
  }

  /// Print out usage information.
  void _printHelp({bool verbose}) {
    print('''The Dart SDK's internal test runner.

    Usage: dart tools/test.dart [options] [selector]

The optional selector limits the tests that will be run. For example, the
selector "language/issue", or equivalently "language/*issue*", limits to test
files matching the regexp ".*issue.*\\.dart" in the "tests/language" directory.

If you specify only a runtime ("-r"), then an appropriate default compiler will
be chosen for that runtime. Likewise, if you specify only a compiler ("-c"),
then a matching runtime is chosen. If neither compiler nor runtime is selected,
the test is run directly from source on the VM.

Options:''');

    print(parser.usage);
  }
}

/// Exception thrown when the arguments could not be parsed.
class OptionParseException implements Exception {
  final String message;

  OptionParseException(this.message);
}

/// Prints the names of the configurations in the test matrix that match the
/// given filter options.
///
/// If any of the options `--system`, `--arch`, `--mode`, `--compiler`,
/// `--nnbd`, or `--runtime` (or their abbreviations) are passed, then only
/// configurations matching those are shown.
void findConfigurations(Map<String, dynamic> options) {
  var testMatrix = TestMatrix.fromPath('tools/bots/test_matrix.json');

  // Default to only showing configurations for the current machine.
  var systemOption = options['system'] as String;
  var system = System.host;
  if (systemOption == 'all') {
    system = null;
  } else if (systemOption != null) {
    system = System.find(systemOption);
  }

  var architectureOption = options['arch'] as List<String>;
  var architectures = [
    if (architectureOption.isEmpty)
      Architecture.x64
    else if (!architectureOption.contains('all'))
      ...architectureOption.map(Architecture.find)
  ];

  var modes = [
    if (options.containsKey('mode'))
      ...(options['mode'] as List<String>).map(Mode.find)
    else
      Mode.release
  ];
  var compilers = [...(options['compiler'] as List<String>).map(Compiler.find)];
  var runtimes = [...(options['runtime'] as List<String>).map(Runtime.find)];

  NnbdMode nnbdMode;
  if (options.containsKey('nnbd')) {
    nnbdMode = NnbdMode.find(options['nnbd'] as String);
  }

  var names = SplayTreeSet<String>();
  for (var configuration in testMatrix.configurations) {
    if (system != null && configuration.system != system) continue;
    if (architectures.isNotEmpty &&
        !architectures.contains(configuration.architecture)) {
      continue;
    }
    if (modes.isNotEmpty && !modes.contains(configuration.mode)) continue;
    if (compilers.isNotEmpty && !compilers.contains(configuration.compiler)) {
      continue;
    }
    if (runtimes.isNotEmpty && !runtimes.contains(configuration.runtime)) {
      continue;
    }
    if (nnbdMode != null && configuration.nnbdMode != nnbdMode) continue;

    names.add(configuration.name);
  }

  var filters = [
    if (system != null) "system=$system",
    if (architectures.isNotEmpty) "arch=$architectures",
    if (modes.isNotEmpty) "mode=$modes",
    if (compilers.isNotEmpty) "compiler=$compilers",
    if (runtimes.isNotEmpty) "runtime=$runtimes",
    if (nnbdMode != null) "nnbd=$nnbdMode",
  ];

  if (filters.isEmpty) {
    print("All configurations:");
  } else {
    print("Configurations where ${filters.join(', ')}:");
  }

  for (var name in names) {
    print("- $name");
  }
}

/// Prints the names of the configurations in the test matrix.
void listConfigurations(Map<String, dynamic> options) {
  var testMatrix = TestMatrix.fromPath('tools/bots/test_matrix.json');

  var names = testMatrix.configurations
      .map((configuration) => configuration.name)
      .toList();
  names.sort();
  names.forEach(print);
}

/// Throws an [OptionParseException] with [message].
void _fail(String message) {
  throw OptionParseException(message);
}

// Returns a map of environment variables to be used with sanitizers.
final Map<String, String> sanitizerEnvironmentVariables = (() {
  final environment = <String, String>{};
  final testMatrixFile = "tools/bots/test_matrix.json";
  final config = json.decode(File(testMatrixFile).readAsStringSync());
  config['sanitizer_options'].forEach((String key, dynamic value) {
    environment[key] = value as String;
  });
  var symbolizerPath =
      config['sanitizer_symbolizer'][Platform.operatingSystem] as String;
  if (symbolizerPath != null) {
    symbolizerPath = path.join(Directory.current.path, symbolizerPath);
    environment['ASAN_SYMBOLIZER_PATH'] = symbolizerPath;
    environment['LSAN_SYMBOLIZER_PATH'] = symbolizerPath;
    environment['MSAN_SYMBOLIZER_PATH'] = symbolizerPath;
    environment['TSAN_SYMBOLIZER_PATH'] = symbolizerPath;
    environment['UBSAN_SYMBOLIZER_PATH'] = symbolizerPath;
  }

  return environment;
})();
