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

// @dart = 2.9

import 'package:testing/testing.dart'
    show Chain, ChainContext, Result, Step, TestDescription, runMe;

import '../tool/dart_doctest_impl.dart';

main([List<String> arguments = const []]) =>
    runMe(arguments, createContext, configurationPath: "../testing.json");

Future<Context> createContext(
    Chain suite, Map<String, String> environment) async {
  return new Context(suite.name);
}

class Context extends ChainContext {
  final String suiteName;

  Context(this.suiteName);

  final List<Step> steps = const <Step>[
    const DartDocTestStep(),
  ];

  // Override special handling of negative tests.
  @override
  Result processTestResult(
      TestDescription description, Result result, bool last) {
    return result;
  }

  Stream<DartDocTestTestDescription> list(Chain suite) async* {
    await for (TestDescription entry in super.list(suite)) {
      List<Test> tests = await dartDocTest.extractTestsFromUri(entry.uri);
      if (tests.isEmpty) continue;
      yield new DartDocTestTestDescription(entry.shortName, entry.uri, tests);
    }
  }

  DartDocTest dartDocTest = new DartDocTest();
}

class DartDocTestTestDescription extends TestDescription {
  final String shortName;
  final Uri uri;
  final List<Test> tests;

  DartDocTestTestDescription(this.shortName, this.uri, this.tests);
}

class DartDocTestStep extends Step<DartDocTestTestDescription,
    DartDocTestTestDescription, Context> {
  const DartDocTestStep();

  String get name => "DartDocTest";

  Future<Result<DartDocTestTestDescription>> run(
      DartDocTestTestDescription description, Context context) async {
    List<TestResult> result = await context.dartDocTest
        .compileAndRun(description.uri, description.tests);
    bool boolResult = result
        .map((e) => e.outcome == TestOutcome.Pass)
        .fold(true, (previousValue, element) => previousValue && element);
    if (boolResult) {
      return new Result<DartDocTestTestDescription>.pass(description);
    } else {
      return new Result<DartDocTestTestDescription>.fail(description);
    }
  }
}
