// Copyright (c) 2016, 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:async/async.dart' hide Result;
import 'package:collection/collection.dart';

import 'package:test_api/src/backend/live_test.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/state.dart'; // ignore: implementation_imports

import 'runner_suite.dart';
import 'live_suite.dart';

/// An implementation of [LiveSuite] that's controlled by a
/// [LiveSuiteController].
class _LiveSuite extends LiveSuite {
  final LiveSuiteController _controller;

  @override
  RunnerSuite get suite => _controller._suite;

  @override
  bool get isComplete => _controller._isComplete;

  @override
  Future get onComplete => _controller._onCompleteGroup.future;

  @override
  bool get isClosed => _controller._onCloseCompleter.isCompleted;

  @override
  Future get onClose => _controller._onCloseCompleter.future;

  @override
  Stream<LiveTest> get onTestStarted =>
      _controller._onTestStartedController.stream;

  @override
  Set<LiveTest> get passed => UnmodifiableSetView(_controller._passed);

  @override
  Set<LiveTest> get skipped => UnmodifiableSetView(_controller._skipped);

  @override
  Set<LiveTest> get failed => UnmodifiableSetView(_controller._failed);

  @override
  LiveTest? get active => _controller._active;

  _LiveSuite(this._controller);
}

/// A controller that drives a [LiveSuite].
///
/// This is a utility class to make it easier for [Engine] to create the
/// [LiveSuite]s exposed by various APIs. The [LiveSuite] is accessible through
/// [LiveSuiteController.liveSuite]. When a live test is run, it should be
/// passed to [reportLiveTest], and once tests are finished being run for this
/// suite, [noMoreLiveTests] should be called. Once the suite should be torn
/// down, [close] should be called.
class LiveSuiteController {
  /// The [LiveSuite] being controlled.
  LiveSuite get liveSuite => _liveSuite;
  late final LiveSuite _liveSuite;

  /// The suite that's being run.
  final RunnerSuite _suite;

  /// The future group that backs [LiveSuite.onComplete].
  ///
  /// This contains all the futures from tests that are run in this suite.
  final _onCompleteGroup = FutureGroup();

  /// Whether [_onCompleteGroup]'s future has fired.
  var _isComplete = false;

  /// The completer that backs [LiveSuite.onClose].
  ///
  /// This is completed when the live suite is closed.
  final _onCloseCompleter = Completer();

  /// The controller for [LiveSuite.onTestStarted].
  final _onTestStartedController =
      StreamController<LiveTest>.broadcast(sync: true);

  /// The set that backs [LiveTest.passed].
  final _passed = <LiveTest>{};

  /// The set that backs [LiveTest.skipped].
  final _skipped = <LiveTest>{};

  /// The set that backs [LiveTest.failed].
  final _failed = <LiveTest>{};

  /// The test exposed through [LiveTest.active].
  LiveTest? _active;

  /// Creates a controller for a live suite representing running the tests in
  /// [suite].
  ///
  /// Once this is called, the controller assumes responsibility for closing the
  /// suite. The caller should call [LiveSuiteController.close] rather than
  /// calling [RunnerSuite.close] directly.
  LiveSuiteController(this._suite) {
    _liveSuite = _LiveSuite(this);

    _onCompleteGroup.future.then((_) {
      _isComplete = true;
    }, onError: (_) {});
  }

  /// Reports the status of [liveTest] through [liveSuite].
  ///
  /// The live test is assumed to be a member of this suite. If [countSuccess]
  /// is `true` (the default), the test is put into [passed] if it succeeds.
  /// Otherwise, it's removed from [liveTests] entirely.
  ///
  /// Throws a [StateError] if called after [noMoreLiveTests].
  void reportLiveTest(LiveTest liveTest, {bool countSuccess = true}) {
    if (_onTestStartedController.isClosed) {
      throw StateError("Can't call reportLiveTest() after noMoreTests().");
    }

    assert(liveTest.suite == _suite);
    assert(_active == null);

    _active = liveTest;

    liveTest.onStateChange.listen((state) {
      if (state.status != Status.complete) return;
      _active = null;

      if (state.result == Result.skipped) {
        _skipped.add(liveTest);
      } else if (state.result != Result.success) {
        _passed.remove(liveTest);
        _failed.add(liveTest);
      } else if (countSuccess) {
        _passed.add(liveTest);
        // A passing test that was once failing was retried
        _failed.remove(liveTest);
      }
    });

    _onTestStartedController.add(liveTest);

    _onCompleteGroup.add(liveTest.onComplete);
  }

  /// Indicates that all the live tests that are going to be provided for this
  /// suite have already been provided.
  void noMoreLiveTests() {
    _onTestStartedController.close();
    _onCompleteGroup.close();
  }

  /// Closes the underlying suite.
  Future close() => _closeMemo.runOnce(() async {
        try {
          await _suite.close();
        } finally {
          _onCloseCompleter.complete();
        }
      });
  final _closeMemo = AsyncMemoizer();
}
