// Copyright (c) 2020, 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:async';
import 'dart:collection';

import 'package:path/path.dart' as p;
import 'package:test_api/backend.dart'; //ignore: deprecated_member_use
import 'package:test_api/src/backend/declarer.dart'; //ignore: implementation_imports
import 'package:test_api/src/backend/group.dart'; //ignore: implementation_imports
import 'package:test_api/src/backend/group_entry.dart'; //ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; //ignore: implementation_imports

import 'runner/configuration.dart';
import 'runner/engine.dart';
import 'runner/plugin/environment.dart';
import 'runner/reporter.dart';
import 'runner/reporter/expanded.dart';
import 'runner/runner_suite.dart';
import 'runner/suite.dart';
import 'util/os.dart';
import 'util/print_sink.dart';

/// Runs all unskipped test cases declared in [testMain].
///
/// Test suite level metadata defined in annotations is not read. No filtering
/// is applied except for the filtering defined by `solo` or `skip` arguments to
/// `group` and `test`. Returns [true] if all tests passed.
Future<bool> directRunTests(FutureOr<void> Function() testMain,
        {Reporter Function(Engine)? reporterFactory}) =>
    _directRunTests(testMain, reporterFactory: reporterFactory);

/// Runs a single test declared in [testMain] matched by it's full test name.
///
/// There must be exactly one test defined with the name [fullTestName]. Note
/// that not all tests and groups are checked, so a test case that is not be
/// intended to be run (due to a `solo` on a different test) may still be run
/// with this API. Only the test names returned by [enumerateTestCases] should
/// be used to prevent running skipped tests.
///
/// Return [true] if the test passes.
///
/// If there are no tests matching [fullTestName] a [MissingTestException] is
/// thrown. If there is more than one test with the name [fullTestName] they
/// will both be run, then a [DuplicateTestnameException] will be thrown.
Future<bool> directRunSingleTest(
        FutureOr<void> Function() testMain, String fullTestName,
        {Reporter Function(Engine)? reporterFactory}) =>
    _directRunTests(testMain,
        reporterFactory: reporterFactory, fullTestName: fullTestName);

Future<bool> _directRunTests(FutureOr<void> Function() testMain,
    {Reporter Function(Engine)? reporterFactory, String? fullTestName}) async {
  reporterFactory ??= (engine) => ExpandedReporter.watch(engine, PrintSink(),
      color: Configuration.empty.color, printPath: false, printPlatform: false);
  final declarer = Declarer(fullTestName: fullTestName);
  await declarer.declare(testMain);

  final suite = RunnerSuite(const PluginEnvironment(), SuiteConfiguration.empty,
      declarer.build(), SuitePlatform(Runtime.vm, os: currentOSGuess),
      path: p.prettyUri(Uri.base));

  final engine = Engine()
    ..suiteSink.add(suite)
    ..suiteSink.close();

  reporterFactory(engine);

  final success = await runZoned(() => Invoker.guard(engine.run),
          zoneValues: {#test.declarer: declarer}) ??
      false;

  if (fullTestName != null) {
    final testCount = engine.liveTests.length;
    if (testCount > 1) {
      throw DuplicateTestNameException(fullTestName);
    }
    if (testCount == 0) {
      throw MissingTestException(fullTestName);
    }
  }
  return success;
}

/// Runs [testMain] and returns the names of all declared tests.
///
/// Test names declared must be unique. If any test repeats the full name,
/// including group prefixes, of a prior test a [DuplicateTestNameException]
/// will be thrown.
///
/// Skipped tests are ignored.
Future<Set<String>> enumerateTestCases(
    FutureOr<void> Function() testMain) async {
  final declarer = Declarer();
  await declarer.declare(testMain);

  final toVisit = Queue<GroupEntry>.of([declarer.build()]);
  final allTestNames = <String>{};
  final unskippedTestNames = <String>{};
  while (toVisit.isNotEmpty) {
    final current = toVisit.removeLast();
    if (current is Group) {
      toVisit.addAll(current.entries.reversed);
    } else if (current is Test) {
      if (!allTestNames.add(current.name)) {
        throw DuplicateTestNameException(current.name);
      }
      if (current.metadata.skip) continue;
      unskippedTestNames.add(current.name);
    } else {
      throw StateError('Unandled Group Entry: ${current.runtimeType}');
    }
  }
  return unskippedTestNames;
}

/// An exception thrown when two test cases in the same test suite (same `main`)
/// have an identical name.
class DuplicateTestNameException implements Exception {
  final String name;
  DuplicateTestNameException(this.name);

  @override
  String toString() => 'A test with the name "$name" was already declared. '
      'Test cases must have unique names.';
}

/// An exception thrown when a specific test was requested by name that does not
/// exist.
class MissingTestException implements Exception {
  final String name;
  MissingTestException(this.name);

  @override
  String toString() =>
      'A test with the name "$name" was not declared in the test suite.';
}
