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

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 {
  @override
  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);

  @override
  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 1'
              ' and `shards`.')
      ..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 1 and $shards,'
            ' 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
      // Turn shard from [1..shards] into [0..shards-1]
      ..shard = shard - 1
      ..configurationName = argResults['named-configuration']
      ..outputDirectory = toUri(argResults['output-directory']);
  }
}
