// Copyright (c) 2015, 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 'package:stack_trace/stack_trace.dart';

import 'closed_exception.dart';
import 'declarer.dart';
import 'group.dart';
import 'live_test.dart';
import 'live_test_controller.dart';
import 'message.dart';
import 'metadata.dart';
import 'state.dart';
import 'suite.dart';
import 'suite_platform.dart';
import 'test.dart';
import 'test_failure.dart';
import 'test_location.dart';
import 'util/pretty_print.dart';

/// A test in this isolate.
class LocalTest extends Test {
  @override
  final String name;

  @override
  final Metadata metadata;

  @override
  final Trace? trace;

  @override
  final TestLocation? location;

  /// Whether this is a test defined using `setUpAll()` or `tearDownAll()`.
  final bool isScaffoldAll;

  /// The test body.
  final FutureOr<void> Function() _body;

  /// Whether the test is run in its own error zone.
  final bool _guarded;

  /// Creates a new [LocalTest].
  ///
  /// If [guarded] is `true`, the test is run in its own error zone, and any
  /// errors that escape that zone cause the test to fail. If it's `false`, it's
  /// the caller's responsibility to invoke [LiveTest.run] in the context of a
  /// call to [Invoker.guard].
  LocalTest(
    this.name,
    this.metadata,
    this._body, {
    this.trace,
    this.location,
    bool guarded = true,
    this.isScaffoldAll = false,
  }) : _guarded = guarded;

  LocalTest._(
    this.name,
    this.metadata,
    this._body,
    this.trace,
    this.location,
    this._guarded,
    this.isScaffoldAll,
  );

  /// Loads a single runnable instance of this test.
  @override
  LiveTest load(Suite suite, {Iterable<Group>? groups}) {
    var invoker = Invoker._(suite, this, groups: groups, guarded: _guarded);
    return invoker.liveTest;
  }

  @override
  Test? forPlatform(SuitePlatform platform) {
    if (!metadata.testOn.evaluate(platform)) return null;
    return LocalTest._(
      name,
      metadata.forPlatform(platform),
      _body,
      trace,
      location,
      _guarded,
      isScaffoldAll,
    );
  }

  @override
  Test? filter(bool Function(Test) callback) {
    if (callback(this)) {
      // filter() always returns new copies because they need to be attached
      // to their new parents.
      return clone();
    }

    return null;
  }

  @override
  Test clone() {
    return LocalTest._(
      name,
      metadata,
      _body,
      trace,
      location,
      _guarded,
      isScaffoldAll,
    );
  }
}

/// The class responsible for managing the lifecycle of a single local test.
///
/// The current invoker is accessible within the zone scope of the running test
/// using [Invoker.current]. It's used to track asynchronous callbacks and
/// report asynchronous errors.
class Invoker {
  /// The live test being driven by the invoker.
  ///
  /// This provides a view into the state of the test being executed.
  LiveTest get liveTest => _controller;
  late final LiveTestController _controller;

  /// Whether to run this test in its own error zone.
  final bool _guarded;

  /// Whether the user code is allowed to interact with the invoker despite it
  /// being closed.
  ///
  /// A test is generally closed because the runner is shutting down (in
  /// response to a signal) or because the test's suite is finished.
  /// Typically calls to [addTearDown] and [addOutstandingCallback] are only
  /// allowed before the test is closed. Tear down callbacks, however, are
  /// allowed to perform these interactions to facilitate resource cleanup on a
  /// best-effort basis, so the invoker is made to appear open only within the
  /// zones running the teardown callbacks.
  bool get _forceOpen => Zone.current[_forceOpenForTearDownKey] as bool;

  /// An opaque object used as a key in the zone value map to identify
  /// [_forceOpen].
  ///
  /// This is an instance variable to ensure that multiple invokers don't step
  /// on one anothers' toes.
  final _forceOpenForTearDownKey = Object();

  /// Whether the test has been closed.
  ///
  /// Once the test is closed, [expect] and [expectAsync] will throw
  /// [ClosedException]s whenever accessed to help the test stop executing as
  /// soon as possible.
  bool get closed => !_forceOpen && _onCloseCompleter.isCompleted;

  /// A future that completes once the test has been closed.
  Future<void> get onClose => _onCloseCompleter.future;
  final _onCloseCompleter = Completer<void>();

  /// The test being run.
  LocalTest get _test => liveTest.test as LocalTest;

  /// The outstanding callback counter for the current zone.
  _AsyncCounter get _outstandingCallbacks {
    var counter = Zone.current[_counterKey] as _AsyncCounter?;
    if (counter != null) return counter;
    throw StateError(
      "Can't add or remove outstanding callbacks outside "
      'of a test body.',
    );
  }

  /// All the zones created by [_waitForOutstandingCallbacks], in the order they
  /// were created.
  ///
  /// This is used to throw timeout errors in the most recent zone.
  final _outstandingCallbackZones = <Zone>[];

  /// An opaque object used as a key in the zone value map to identify
  /// [_outstandingCallbacks].
  ///
  /// This is an instance variable to ensure that multiple invokers don't step
  /// on one anothers' toes.
  final _counterKey = Object();

  /// The number of times this [liveTest] has been run.
  int _runCount = 0;

  /// The current invoker, or `null` if none is defined.
  ///
  /// An invoker is only set within the zone scope of a running test.
  static Invoker? get current {
    // TODO(nweiz): Use a private symbol when dart2js supports it (issue 17526).
    return Zone.current[#test.invoker] as Invoker?;
  }

  /// Runs [callback] in a zone where unhandled errors from [LiveTest]s are
  /// caught and dispatched to the appropriate [Invoker].
  static T? guard<T>(T Function() callback) => runZoned<T?>(
    callback,
    zoneSpecification: ZoneSpecification(
      // Use [handleUncaughtError] rather than [onError] so we can
      // capture [zone] and with it the outstanding callback counter for
      // the zone in which [error] was thrown.
      handleUncaughtError: (self, _, zone, error, stackTrace) {
        var invoker = zone[#test.invoker] as Invoker?;
        if (invoker != null) {
          self.parent!.run(() => invoker._handleError(zone, error, stackTrace));
        } else {
          self.parent!.handleUncaughtError(error, stackTrace);
        }
      },
    ),
  );

  /// The timer for tracking timeouts.
  ///
  /// This will be `null` until the test starts running.
  Timer? _timeoutTimer;

  /// The tear-down functions to run when this test finishes.
  final _tearDowns = <void Function()>[];

  /// Messages to print if and when this test fails.
  final _printsOnFailure = <String>[];

  Invoker._(
    Suite suite,
    LocalTest test, {
    Iterable<Group>? groups,
    bool guarded = true,
  }) : _guarded = guarded {
    _controller = LiveTestController(
      suite,
      test,
      _onRun,
      _onCloseCompleter.complete,
      groups: groups,
    );
  }

  /// Runs [callback] after this test completes.
  ///
  /// The [callback] may return a [Future]. Like all tear-downs, callbacks are
  /// run in the reverse of the order they're declared.
  void addTearDown(FutureOr<dynamic> Function() callback) {
    if (closed) throw ClosedException();

    if (_test.isScaffoldAll) {
      Declarer.current!.addTearDownAll(callback);
    } else {
      _tearDowns.add(callback);
    }
  }

  /// Tells the invoker that there's a callback running that it should wait for
  /// before considering the test successful.
  ///
  /// Each call to [addOutstandingCallback] should be followed by a call to
  /// [removeOutstandingCallback] once the callback is no longer running. Note
  /// that only successful tests wait for outstanding callbacks; as soon as a
  /// test experiences an error, any further calls to [addOutstandingCallback]
  /// or [removeOutstandingCallback] will do nothing.
  ///
  /// Throws a [ClosedException] if this test has been closed.
  void addOutstandingCallback() {
    if (closed) throw ClosedException();
    _outstandingCallbacks.increment();
  }

  /// Tells the invoker that a callback declared with [addOutstandingCallback]
  /// is no longer running.
  void removeOutstandingCallback() {
    heartbeat();
    _outstandingCallbacks.decrement();
  }

  /// Run [tearDowns] in reverse order.
  ///
  /// An exception thrown in a tearDown callback will cause the test to fail, if
  /// it isn't already failing, but it won't prevent the remaining callbacks
  /// from running. This invoker will not be closeable within the zone that the
  /// teardowns are running in.
  Future<void> runTearDowns(List<FutureOr<void> Function()> tearDowns) {
    heartbeat();
    return runZoned(() async {
      while (tearDowns.isNotEmpty) {
        var completer = Completer<void>();

        addOutstandingCallback();
        _waitForOutstandingCallbacks(() {
          Future.sync(tearDowns.removeLast()).whenComplete(completer.complete);
        }).then((_) => removeOutstandingCallback()).unawaited;

        await completer.future;
      }
    }, zoneValues: {_forceOpenForTearDownKey: true});
  }

  /// Runs [fn] and completes once [fn] and all outstanding callbacks registered
  /// within [fn] have completed.
  ///
  /// Outstanding callbacks registered within [fn] will *not* be registered as
  /// outstanding callback outside of [fn].
  Future<void> _waitForOutstandingCallbacks(FutureOr<void> Function() fn) {
    heartbeat();

    Zone? zone;
    var counter = _AsyncCounter();
    runZoned(() async {
      zone = Zone.current;
      _outstandingCallbackZones.add(zone!);
      try {
        await fn();
      } finally {
        counter.decrement();
      }
    }, zoneValues: {_counterKey: counter});

    return counter.onZero.whenComplete(() {
      _outstandingCallbackZones.remove(zone!);
    });
  }

  /// Notifies the invoker that progress is being made.
  ///
  /// Each heartbeat resets the timeout timer. This helps ensure that
  /// long-running tests that still make progress don't time out.
  void heartbeat() {
    if (liveTest.isComplete) return;
    if (_timeoutTimer != null) _timeoutTimer!.cancel();
    if (liveTest.suite.ignoreTimeouts == true) return;

    const defaultTimeout = Duration(seconds: 30);
    var timeout = liveTest.test.metadata.timeout.apply(defaultTimeout);
    if (timeout == null) return;
    String message() {
      var message = 'Test timed out after ${niceDuration(timeout)}.';
      if (timeout == defaultTimeout) {
        message += ' See https://pub.dev/packages/test#timeouts';
      }
      return message;
    }

    _timeoutTimer = Zone.root.createTimer(timeout, () {
      _outstandingCallbackZones.last.run(() {
        _handleError(Zone.current, TimeoutException(message(), timeout));
        _outstandingCallbacks.complete();
      });
    });
  }

  /// Marks the current test as skipped.
  ///
  /// If passed, [message] is emitted as a skip message.
  ///
  /// Note that this *does not* mark the test as complete. That is, it sets
  /// the result to [Result.skipped], but doesn't change the state.
  void skip([String? message]) {
    if (liveTest.state.shouldBeDone) {
      // Set the state explicitly so we don't get an extra error about the test
      // failing after being complete.
      _controller.setState(const State(Status.complete, Result.error));
      throw 'This test was marked as skipped after it had already completed.\n'
          'Make sure to use a matching library which informs the test runner\n'
          'of pending async work.';
    }

    if (message != null) _controller.message(Message.skip(message));
    // TODO: error if the test is already complete.
    _controller.setState(const State(Status.pending, Result.skipped));
  }

  /// Prints [message] if and when this test fails.
  void printOnFailure(String message) {
    message = message.trim();
    if (liveTest.state.result.isFailing) {
      _print('\n$message');
    } else {
      _printsOnFailure.add(message);
    }
  }

  /// Notifies the invoker of an asynchronous error.
  ///
  /// The [zone] is the zone in which the error was thrown.
  void _handleError(Zone zone, Object error, [StackTrace? stackTrace]) {
    // Ignore errors propagated from previous test runs
    if (_runCount != zone[#runCount]) return;

    // Get the chain information from the zone in which the error was thrown.
    zone.run(() {
      if (stackTrace == null) {
        stackTrace = Chain.current();
      } else {
        stackTrace = Chain.forTrace(stackTrace!);
      }
    });

    // Store these here because they'll change when we set the state below.
    var shouldBeDone = liveTest.state.shouldBeDone;

    if (error is! TestFailure) {
      _controller.setState(const State(Status.complete, Result.error));
    } else if (liveTest.state.result != Result.error) {
      _controller.setState(const State(Status.complete, Result.failure));
    }

    _controller.addError(error, stackTrace!);

    if (_printsOnFailure.isNotEmpty) {
      _print(_printsOnFailure.join('\n\n'));
      _printsOnFailure.clear();
    }

    // If a test was supposed to be done but then had an error, that indicates
    // that it was poorly-written and could be flaky.
    if (!shouldBeDone) return;

    // However, users don't think of load tests as "tests", so the error isn't
    // helpful for them.
    if (liveTest.suite.isLoadSuite) return;

    _handleError(
      zone,
      'This test failed after it had already completed.\n'
      'Make sure to use a matching library which informs the test runner\n'
      'of pending async work.',
      stackTrace,
    );
  }

  /// The method that's run when the test is started.
  void _onRun() {
    _controller.setState(const State(Status.running, Result.success));

    _runCount++;
    Chain.capture(
      () {
        _guardIfGuarded(() {
          runZoned(
            () async {
              // Run the test asynchronously so that the "running" state change
              // has a chance to hit its event handler(s) before the test produces
              // an error. If an error is emitted before the first state change is
              // handled, we can end up with [onError] callbacks firing before the
              // corresponding [onStateChange], which violates the timing
              // guarantees.
              //
              // Use the event loop over the microtask queue to avoid starvation.
              await Future(() {});

              await _waitForOutstandingCallbacks(_test._body);
              await _waitForOutstandingCallbacks(
                () => runTearDowns(_tearDowns),
              );

              if (_timeoutTimer != null) _timeoutTimer!.cancel();

              if (liveTest.state.result != Result.success &&
                  _runCount < liveTest.test.metadata.retry + 1) {
                _controller.message(
                  Message.print('Retry: ${liveTest.test.name}'),
                );
                _onRun();
                return;
              }

              _controller.setState(
                State(Status.complete, liveTest.state.result),
              );

              _controller.completer.complete();
            },
            zoneValues: {
              #test.invoker: this,
              _forceOpenForTearDownKey: false,
              #runCount: _runCount,
            },
            zoneSpecification: ZoneSpecification(
              print: (_, _, _, line) => _print(line),
            ),
          );
        });
      },
      when: liveTest.test.metadata.chainStackTraces,
      errorZone: false,
    );
  }

  /// Runs [callback], in a [Invoker.guard] context if [_guarded] is `true`.
  void _guardIfGuarded(void Function() callback) {
    if (_guarded) {
      Invoker.guard(callback);
    } else {
      callback();
    }
  }

  /// Prints [text] as a message to [_controller].
  void _print(String text) => _controller.message(Message.print(text));
}

/// A manually incremented/decremented counter that completes a [Future] the
/// first time it reaches zero or is forcefully completed.
class _AsyncCounter {
  var _count = 1;

  /// A Future that completes the first time the counter reaches 0.
  Future<void> get onZero => _completer.future;
  final _completer = Completer<void>();

  void increment() {
    _count++;
  }

  void decrement() {
    _count--;
    if (_count != 0) return;
    if (_completer.isCompleted) return;
    _completer.complete();
  }

  /// Force [onZero] to complete.
  ///
  /// No effect if [onZero] has already completed.
  void complete() {
    if (!_completer.isCompleted) _completer.complete();
  }
}

extension<T> on Future<T> {
  void get unawaited {}
}
