// 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:async/async.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports

import 'environment.dart';
import 'suite.dart';

/// A suite produced and consumed by the test runner that has runner-specific
/// logic and lifecycle management.
///
/// This is separated from [Suite] because the backend library (which will
/// eventually become its own package) is primarily for test code itself to use,
/// for which the [RunnerSuite] APIs don't make sense.
///
/// A [RunnerSuite] can be produced and controlled using a
/// [RunnerSuiteController].
class RunnerSuite extends Suite {
  final RunnerSuiteController _controller;

  /// The environment in which this suite runs.
  Environment get environment => _controller._environment;

  /// The configuration for this suite.
  SuiteConfiguration get config => _controller._config;

  /// Whether the suite is paused for debugging.
  ///
  /// When using a dev inspector, this may also mean that the entire browser is
  /// paused.
  bool get isDebugging => _controller._isDebugging;

  /// A broadcast stream that emits an event whenever the suite is paused for
  /// debugging or resumed afterwards.
  ///
  /// The event is `true` when debugging starts and `false` when it ends.
  Stream<bool> get onDebugging => _controller._onDebuggingController.stream;

  /// Returns a channel that communicates with the remote suite.
  ///
  /// This connects to a channel created by code in the test worker calling
  /// `suiteChannel()` from `remote_platform_helpers.dart` with the same name.
  /// It can be used used to send and receive any JSON-serializable object.
  StreamChannel channel(String name) => _controller.channel(name);

  /// A shortcut constructor for creating a [RunnerSuite] that never goes into
  /// debugging mode and doesn't support suite channels.
  factory RunnerSuite(Environment environment, SuiteConfiguration config,
      Group group, SuitePlatform platform,
      {String? path, Function()? onClose}) {
    var controller =
        RunnerSuiteController._local(environment, config, onClose: onClose);
    var suite = RunnerSuite._(controller, group, platform, path: path);
    controller._suite = Future.value(suite);
    return suite;
  }

  RunnerSuite._(this._controller, Group group, SuitePlatform platform,
      {String? path})
      : super(group, platform, path: path);

  @override
  RunnerSuite filter(bool Function(Test) callback) {
    var filtered = group.filter(callback);
    filtered ??= Group.root([], metadata: metadata);
    return RunnerSuite._(_controller, filtered, platform, path: path);
  }

  /// Closes the suite and releases any resources associated with it.
  Future close() => _controller._close();

  /// Collects a hit-map containing merged coverage.
  ///
  /// Result is suitable for input to the coverage formatters provided by
  /// `package:coverage`.
  Future<Map<String, dynamic>> gatherCoverage() async {
    // TODO(https://github.com/dart-lang/sdk/issues/41108): Remove cast
    var coverage =
        // ignore: unnecessary_cast
        await _controller._gatherCoverage?.call() as Map<String, dynamic>?;
    return coverage ?? {};
  }
}

/// A class that exposes and controls a [RunnerSuite].
class RunnerSuiteController {
  /// The suite controlled by this controller.
  Future<RunnerSuite> get suite => _suite;
  late final Future<RunnerSuite> _suite;

  /// The backing value for [suite.environment].
  final Environment _environment;

  /// The configuration for this suite.
  final SuiteConfiguration _config;

  /// A channel that communicates with the remote suite.
  final MultiChannel? _suiteChannel;

  /// The function to call when the suite is closed.
  final Function()? _onClose;

  /// The backing value for [suite.isDebugging].
  bool _isDebugging = false;

  /// The controller for [suite.onDebugging].
  final _onDebuggingController = StreamController<bool>.broadcast();

  /// The channel names that have already been used.
  final _channelNames = <String>{};

  /// Collects a hit-map containing merged coverage.
  final Future<Map<String, dynamic>> Function()? _gatherCoverage;

  RunnerSuiteController(this._environment, this._config, this._suiteChannel,
      Future<Group> groupFuture, SuitePlatform platform,
      {String? path,
      Function()? onClose,
      Future<Map<String, dynamic>> Function()? gatherCoverage})
      : _onClose = onClose,
        _gatherCoverage = gatherCoverage {
    _suite = groupFuture
        .then((group) => RunnerSuite._(this, group, platform, path: path));
  }

  /// Used by [new RunnerSuite] to create a runner suite that's not loaded from
  /// an external source.
  RunnerSuiteController._local(this._environment, this._config,
      {Function()? onClose,
      Future<Map<String, dynamic>> Function()? gatherCoverage})
      : _suiteChannel = null,
        _onClose = onClose,
        _gatherCoverage = gatherCoverage;

  /// Sets whether the suite is paused for debugging.
  ///
  /// If this is different than [suite.isDebugging], this will automatically
  /// send out an event along [suite.onDebugging].
  void setDebugging(bool debugging) {
    if (debugging == _isDebugging) return;
    _isDebugging = debugging;
    _onDebuggingController.add(debugging);
  }

  /// Returns a channel that communicates with the remote suite.
  ///
  /// This connects to a channel created by code in the test worker calling
  /// `suiteChannel()` from `remote_platform_helpers.dart` with the same name.
  /// It can be used used to send and receive any JSON-serializable object.
  ///
  /// This is exposed on the [RunnerSuiteController] so that runner plugins can
  /// communicate with the workers they spawn before the associated [suite] is
  /// fully loaded.
  StreamChannel channel(String name) {
    if (!_channelNames.add(name)) {
      throw StateError('Duplicate RunnerSuite.channel() connection "$name".');
    }

    var suiteChannel = _suiteChannel;
    if (suiteChannel == null) {
      throw StateError('No suite channel set up but one was requested.');
    }

    var channel = suiteChannel.virtualChannel();
    suiteChannel.sink
        .add({'type': 'suiteChannel', 'name': name, 'id': channel.id});
    return channel;
  }

  /// The backing function for [suite.close].
  Future _close() => _closeMemo.runOnce(() async {
        await _onDebuggingController.close();
        var onClose = _onClose;
        if (onClose != null) await onClose();
      });
  final _closeMemo = AsyncMemoizer();
}
