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

import 'dart:async';

import 'package:stack_trace/stack_trace.dart';

import 'src/backend/closed_exception.dart';
import 'src/backend/invoker.dart';
import 'src/backend/stack_trace_formatter.dart';

export 'src/backend/test_failure.dart' show TestFailure;
export 'src/scaffolding/utils.dart' show pumpEventQueue;

final class TestHandle {
  /// Returns handle for the currently running test.
  ///
  /// This must be called from within the zone that the test is running in. If
  /// the current zone is not a test's zone throws [OutsideTestException].
  static TestHandle get current {
    final invoker = Invoker.current;
    if (invoker == null) throw OutsideTestException();
    return TestHandle._(
      invoker,
      StackTraceFormatter.current ?? _defaultFormatter,
    );
  }

  static final _defaultFormatter = StackTraceFormatter();

  final Invoker _invoker;
  final StackTraceFormatter _stackTraceFormatter;
  TestHandle._(this._invoker, this._stackTraceFormatter);

  String get name => _invoker.liveTest.test.name;

  /// Whether this test has already completed successfully.
  ///
  /// If a callback originating from a test case is invoked after the test has
  /// already passed it may be an indication of a test that fails to wait for
  /// all work to be finished, or of an asynchronous callback that is called
  /// more times or later than expected.
  bool get shouldBeDone => _invoker.liveTest.state.shouldBeDone;

  /// Marks this test as skipped.
  ///
  /// A skipped test may still fail if any exception is thrown, including
  /// uncaught asynchronous errors.
  void markSkipped(String message) {
    if (_invoker.closed) throw ClosedException();
    _invoker.skip(message);
  }

  /// Indicates that this test should not be considered done until the returned
  /// [OutstandingWork] is marked as complete.
  ///
  /// The test may time out before the outstanding work completes.
  OutstandingWork markPending() {
    if (_invoker.closed) throw ClosedException();
    return OutstandingWork._(_invoker, Zone.current);
  }

  /// Converts [stackTrace] to a [Chain] according to the current test's
  /// configuration.
  Chain formatStackTrace(StackTrace stackTrace) =>
      _stackTraceFormatter.formatStackTrace(stackTrace);
}

final class OutstandingWork {
  final Invoker _invoker;
  final Zone _zone;
  var _isComplete = false;
  OutstandingWork._(this._invoker, this._zone) {
    _invoker.addOutstandingCallback();
  }
  void complete() {
    if (_isComplete) return;
    _isComplete = true;
    _zone.run(_invoker.removeOutstandingCallback);
  }
}

final class OutsideTestException implements Exception {}
