// Copyright 2013 The Flutter Authors. 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:io' show stdout;
import 'dart:isolate';

import 'package:async_helper/async_minitest.dart' as m;
import 'package:expect/expect.dart' as e;

/// The state that each [Test] may be in.
enum TestState {
  /// Initial state of a [Test] after it has been allocated.
  allocated,

  /// State of a [Test] when it is on the queue of a [TestSuite].
  queued,

  /// State of a [Test] when it has been started.
  started,

  /// State of a [Test] when it has succeeded.
  succeeded,

  /// State of a [Test] when it has failed.
  failed,
}

/// A test that a [TestSuite] can enqueue to run.
class Test {
  /// Creates a [Test] with the given name, body, logger, and lifecycle.
  Test(
    this.name,
    this.body, {
    StringSink? logger,
    TestLifecycle? lifecycle,
  }) :
    _logger = logger ?? stdout,
    _lifecycle = lifecycle ?? _DefaultTestLifecycle(name);

  /// The name of the test.
  final String name;

  /// The body of the test.
  final dynamic Function() body;

  /// The logger that records information about the test.
  final StringSink _logger;

  /// The state that the test is in.
  TestState state = TestState.allocated;

  final TestLifecycle _lifecycle;

  /// Runs the test.
  ///
  /// Also signals the test's progress to the [TestLifecycle] object
  /// that was provided when the [Test] was constructed, which will eventually
  /// call the provided [onDone] callback.
  void run({
    void Function()? onDone,
  }) {
    m.test(name, () async {
      await Future<void>(() async {
        state = TestState.started;
        _logger.writeln('Test "$name": Started');
        try {
          await body();
          state = TestState.succeeded;
          _logger.writeln('Test "$name": Passed');
        } on e.ExpectException catch (e, st) {
          state = TestState.failed;
          _logger.writeln('Test "$name": Failed\n$e\n$st');
        } finally {
          _lifecycle.onDone(cleanup: onDone);
        }
      });
    });
    _lifecycle.onStart();
  }
}

/// Callbacks for the lifecycle of a test.
abstract class TestLifecycle {
  /// Called after a test has started.
  void onStart();

  /// Called when a test is finished.
  ///
  /// The callback should ensure that the [cleanup] function should run
  /// eventually if provided.
  void onDone({void Function()? cleanup});
}

class _DefaultTestLifecycle implements TestLifecycle {
  _DefaultTestLifecycle(String name) : _port = ReceivePort(name);

  final ReceivePort _port;

  void Function()? _cleanup;

  @override
  void onStart() {
    _port.listen((dynamic msg) {
      _port.close();
      if (_cleanup != null) {
        _cleanup!();
      }
    });
  }

  @override
  void onDone({void Function()? cleanup}) {
    _port.sendPort.send(null);
    _cleanup = cleanup;
  }
}
