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

/// A runner that executes a pipeline on a folder containing modular tests.
import 'dart:io';

import 'package:args/args.dart';
import 'package:modular_test/src/io_pipeline.dart';
import 'package:modular_test/src/loader.dart';
import 'package:modular_test/src/suite.dart';

import 'generic_runner.dart' as generic;

Uri relativize(Uri uri, Uri base) {
  return Uri.parse(uri.path.substring(base.path.length));
}

Future<void> runSuite(Uri suiteFolder, String suiteName, Options options,
    IOPipeline pipeline) async {
  var dir = Directory.fromUri(suiteFolder);
  var entries = (await dir.list(recursive: false).toList())
      .whereType<Directory>()
      .map((e) => _PipelineTest(e.uri, suiteFolder, options, pipeline))
      .toList();

  await generic.runSuite(
      entries,
      generic.RunnerOptions(
          suiteName: suiteName,
          configurationName: options.configurationName,
          filter: options.filter,
          logDir: options.outputDirectory,
          shard: options.shard,
          shards: options.shards,
          verbose: options.verbose,
          reproTemplate: '%executable %script --verbose --filter %name'));
  await pipeline.cleanup();
}

class _PipelineTest implements generic.Test {
  final String name;
  final Uri uri;
  final Options options;
  final IOPipeline pipeline;

  _PipelineTest(this.uri, Uri suiteFolder, this.options, this.pipeline)
      // Use the name of the folder as the test name by trimming out the prefix
      // from the suite and the trailing `/`.
      : name = uri.path.substring(suiteFolder.path.length, uri.path.length - 1);

  Future<void> run() async {
    ModularTest test = await loadTest(uri);
    if (options.verbose) print(test.debugString());
    await pipeline.run(test);
  }
}

class Options {
  bool showSkipped = false;
  bool verbose = false;
  String? filter;
  int shards = 1;
  int shard = 1;
  String? configurationName;
  Uri? outputDirectory;
  bool useSdk = false;

  static Options parse(List<String> args) {
    var parser = ArgParser()
      ..addFlag('verbose',
          abbr: 'v',
          defaultsTo: false,
          help: 'print detailed information about the test and modular steps')
      ..addFlag('show-skipped',
          defaultsTo: false,
          help: 'print the name of the tests skipped by the filtering option')
      ..addFlag('use-sdk',
          defaultsTo: false, help: 'whether to use snapshots from a built sdk')
      ..addOption('filter',
          help: 'only run tests containing this filter as a substring')
      ..addOption('shards',
          help: 'total number of shards a suite is going to be split into.',
          defaultsTo: '1')
      ..addOption('shard',
          help: 'which shard this script is executing. This should be between 0'
              ' and `shards - 1`.')
      ..addOption('output-directory',
          help: 'location where to emit the jsonl result and log files')
      ..addOption('named-configuration',
          abbr: 'n',
          help: 'configuration name to use for emitting jsonl result files.');
    ArgResults argResults = parser.parse(args);
    int shards = int.tryParse(argResults['shards']) ?? 1;
    int shard = 1;
    if (shards > 1) {
      shard = int.tryParse(argResults['shard']) ?? 1;
      if (shard <= 0 || shard >= shards) {
        print('Error: shard should be between 0 and ${shards - 1},'
            ' but got $shard');
        exit(1);
      }
    }
    Uri? toUri(s) => s == null ? null : Uri.base.resolveUri(Uri.file(s));
    return Options()
      ..showSkipped = argResults['show-skipped']
      ..verbose = argResults['verbose']
      ..useSdk = argResults['use-sdk']
      ..filter = argResults['filter']
      ..shards = shards
      ..shard = shard
      ..configurationName = argResults['named-configuration']
      ..outputDirectory = toUri(argResults['output-directory']);
  }
}
