// Copyright (c) 2024, 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';

// Checks that an `Error` object that is "thrown" through async functionality
// gets a stack trace set.

import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';

main() async {
  asyncStart();

  for ((String, Object, StackTrace, Object, String, AsyncError?) Function()
      setUp
      in [
        () {
          // Without error callback. Inject and expect same fresh error.
          var error = StateError("Quo!");
          var stack = StackTrace.fromString("Secret stack");
          return ("", error, stack, error, stack.toString(), null);
        },
        () {
          // With error callback, same error, new stack.
          var error = StateError("Quo");
          var stack = StackTrace.fromString("Secret stack");
          var stack2 = StackTrace.fromString("Other stack");
          var errorCallback = AsyncError(error, stack2);
          return (
            "errorCallback: fresh both",
            error,
            stack,
            error,
            stack2.toString(),
            errorCallback,
          );
        },
        () {
          // With error callback, new error, stack.
          var error = StateError("Quo");
          var stack = StackTrace.fromString("Secret stack");
          var error2 = StateError("Quid");
          var stack2 = StackTrace.fromString("Other stack");
          var errorCallback = AsyncError(error2, stack2);
          return (
            "errorCallback: fresh stack",
            error,
            stack,
            error2,
            stack2.toString(),
            errorCallback,
          );
        },
      ]) {
    Future<void> test(
      String name,
      Future<(Object, StackTrace)> Function(Object, StackTrace) body,
    ) {
      var (msg, error, stack, expectError, expectStackString, errorCallback) =
          setUp();
      print("Test: $name${msg.isNotEmpty ? ", $msg" : msg}");

      return asyncTest(
        () =>
            runZoned(
              () => body(error, stack),
              zoneSpecification: ZoneSpecification(
                errorCallback: (s, p, z, e, st) => errorCallback,
              ),
            ).then((es) {
              var (e, s) = es;
              Expect.identical(expectError, e, name);
              Expect.equals(expectStackString, s.toString(), name);
              Expect.equals(
                expectStackString,
                (e as Error).stackTrace.toString(),
                name,
              );
            }),
      );
    }

    // Sanity check: Plain throws.
    () {
      var (name, error, stack, error2, stack2, errorCallback) = setUp();
      try {
        Error.throwWithStackTrace(error, stack);
      } catch (e, s) {
        Expect.identical(error, e, "Error.throw");
        Expect.equals(stack.toString(), s.toString(), "Error.throw");
        Expect.equals(
          stack.toString(),
          (e as Error).stackTrace.toString(),
          "Error.throw",
        );
      }
    }();

    // Futures.

    // Immediate error.
    await test(
      "Future.error",
      (error, stack) => futureError(Future.error(error, stack)),
    );

    // Through controller, async.
    await test("Completer().completeError", (error, stack) {
      var completer = Completer<void>();
      completer.completeError(error, stack);
      return futureError(completer.future);
    });

    // Through controller, sync.
    await test("Completer.sync().completeError", (error, stack) {
      var completer = Completer<void>.sync();
      var future = completer.future..ignore();
      completer.completeError(error, stack);
      return futureError(future);
    });

    // Streams.

    // Singleton error.
    await test(
      "Stream.error",
      (error, stack) => streamError(Stream.error(error, stack)),
    );

    // Controller errors.
    for (var broadcast in [false, true]) {
      for (var sync in [false, true]) {
        await test(
          "Stream${broadcast ? ".broadcast" : ""}${sync ? "(sync)" : ""}",
          (error, stack) {
            var controller = broadcast
                ? StreamController<void>.broadcast(sync: sync)
                : StreamController<void>(sync: sync);
            var future = streamError(controller.stream)..ignore();
            controller.addError(error, stack);
            return future;
          },
        );
      }
    }
  }

  asyncEnd();
}

// --------------------------------------------------------------------
// Helper functions

(Object, StackTrace) captureError(Object e, StackTrace s) => (e, s);

(Object, StackTrace) fail(_) {
  Expect.fail("No error from future") as Never;
}

/// Captures error of future.
Future<(Object, StackTrace)> futureError(Future<void> future) =>
    future.then(fail, onError: captureError);

/// Captures first error of stream.
Future<(Object, StackTrace)> streamError(Stream<void> stream) {
  var c = Completer<(Object, StackTrace)>();
  var sub = stream.listen(
    (_) {
      // No values expected.
    },
    onError: (Object e, StackTrace s) {
      c.complete((e, s));
    },
    onDone: () {
      Expect.fail("No error from stream");
    },
    cancelOnError: true,
  );
  return c.future;
}
