// Copyright (c) 2022, 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:isolate';
import 'dart:async';
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';

void main() async {
  asyncStart();
  // Sending result back.
  await testValue();
  await testAsyncValue();
  // Sending error from computation back.
  await testError();
  await testAsyncError();
  // Sending uncaught async error back.
  await testUncaughtError();
  // Not sending anything back before isolate dies.
  await testIsolateHangs();
  await testIsolateKilled();
  await testIsolateExits();
  // Failing to start.
  await testInvalidMessage();
  asyncEnd();
}

final StackTrace stack = StackTrace.fromString("Known Stacktrace");
final ArgumentError error = ArgumentError.value(42, "name");

var variable = 0;

Future<void> testValue() async {
  var value = await Isolate.run<int>(() {
    variable = 1; // Changed in other isolate!
    Expect.equals(1, variable);
    return 42;
  });
  Expect.equals(42, value);
  Expect.equals(0, variable);
}

Future<void> testAsyncValue() async {
  var value = await Isolate.run<int>(() async {
    variable = 1;
    return 42;
  });
  Expect.equals(42, value);
  Expect.equals(0, variable);
}

Future<void> testError() async {
  var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() {
    variable = 1;
    Error.throwWithStackTrace(error, stack);
  }));
  Expect.equals(42, e.invalidValue);
  Expect.equals("name", e.name);
  Expect.equals(0, variable);
}

Future<void> testAsyncError() async {
  var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() async {
    variable = 1;
    Error.throwWithStackTrace(error, stack);
  }));
  Expect.equals(42, e.invalidValue);
  Expect.equals("name", e.name);
  Expect.equals(0, variable);
}

Future<void> testUncaughtError() async {
  var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
    variable = 1;
    unawaited(Future.error(error, stack)); // Uncaught error
    await Completer().future; // Never completes.
    return -1;
  }));

  Expect.type<RemoteError>(e);
  Expect.equals(error.toString(), e.toString());
  Expect.equals(0, variable);
}

Future<void> testIsolateHangs() async {
  var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
    variable = 1;
    await Completer<Never>().future; // Never completes.
    // Isolate should end while hanging here, because its event loop is empty.
  }));
  Expect.type<RemoteError>(e);
  Expect.equals("Computation ended without result", e.toString());
  Expect.equals(0, variable);
}

Future<void> testIsolateKilled() async {
  var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
    variable = 1;
    Isolate.current.kill(); // Send kill request.
    await Completer<Never>().future; // Never completes.
    // Isolate should get killed while hanging here.
  }));
  Expect.type<RemoteError>(e);
  Expect.equals("Computation ended without result", e.toString());
  Expect.equals(0, variable);
}

Future<void> testIsolateExits() async {
  var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
    variable = 1;
    Isolate.exit(); // Dies here without sending anything back.
  }));
  Expect.type<RemoteError>(e);
  Expect.equals("Computation ended without result", e.toString());
  Expect.equals(0, variable);
}

Future<void> testInvalidMessage() async {
  // Regression test for http://dartbug.com/48516
  var unsendable = RawReceivePort();
  await asyncExpectThrows<Error>(Isolate.run<void>(() => unsendable));
  unsendable.close();
  // Test should not hang.
}
