// Copyright (c) 2023, 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.

// Dart test program for testing dart:ffi async callbacks.
//
// VMOptions=
// VMOptions=--use-slow-path
// VMOptions=--use-slow-path --stacktrace-every=100
// VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects
// VMOptions=--test_il_serialization
// VMOptions=--profiler --profile_vm=true
// VMOptions=--profiler --profile_vm=false
// SharedObjects=ffi_test_functions

import 'dart:async';
import 'dart:ffi';
import 'dart:isolate';

import 'dart:io';

import "package:expect/expect.dart";

import 'dylib_utils.dart';

main(args, message) async {
  if (message != null) {
    // We've been spawned by Isolate.spawnUri. Run IsolateB.
    await IsolateB.entryPoint(message);
    return;
  }

  // Simple tests.
  await testNativeCallableHelloWorld();
  testNativeCallableDoubleCloseError();
  await testNativeCallableUseAfterFree();
  await testNativeCallableNestedCloseCall();
  await testNativeCallableThrowInsideCallback();
  await testNativeCallableDontKeepAlive();
  testNativeCallableKeepAliveGetter();
  await testNativeCallableClosure();

  // Message passing tests.
  globalVar = 1000;
  for (final sameGroup in [true, false]) {
    final isolateA = IsolateA(sameGroup);
    await isolateA.messageLoop();
    isolateA.close();
  }
  print("All tests completed :)");
}

final List<TestCase> messagePassingTestCases = [
  SanityCheck(),
  CallFromIsoAToIsoB(),
  CallFromIsoBToIsoA(),
  CallFromIsoAToIsoBViaNewThreadBlocking(),
  CallFromIsoBToIsoAViaNewThreadBlocking(),
  CallFromIsoAToIsoBViaNewThreadNonBlocking(),
  CallFromIsoBToIsoAViaNewThreadNonBlocking(),
  CallFromIsoAToBToA(),
  CallFromIsoBToAToB(),
  ManyCallsBetweenIsolates(),
  ManyCallsBetweenIsolatesViaNewThreadBlocking(),
  ManyCallsBetweenIsolatesViaNewThreadNonBlocking(),
];

var simpleFunctionResult = Completer<int>();
void simpleFunction(int a, int b) {
  simpleFunctionResult.complete(a + b);
}

Future<void> testNativeCallableHelloWorld() async {
  final lib = NativeLibrary();
  final callback = NativeCallable<CallbackNativeType>.listener(simpleFunction);

  simpleFunctionResult = Completer<int>();
  lib.callFunctionOnSameThread(1000, callback.nativeFunction);

  Expect.equals(1123, await simpleFunctionResult.future);
  callback.close();
}

testNativeCallableDoubleCloseError() {
  final callback = NativeCallable<CallbackNativeType>.listener(simpleFunction);
  Expect.notEquals(nullptr, callback.nativeFunction);
  callback.close();

  Expect.throwsStateError(() {
    final _ = callback.nativeFunction;
  });

  // Expect that these do not throw.
  callback.close();
  callback.keepIsolateAlive = true;
  Expect.isFalse(callback.keepIsolateAlive);
}

Future<void> testNativeCallableUseAfterFree() async {
  final lib = NativeLibrary();

  final callback = NativeCallable<CallbackNativeType>.listener(simpleFunction);
  final nativeFunction = callback.nativeFunction;
  callback.close();

  simpleFunctionResult = Completer<int>();
  lib.callFunctionOnSameThread(123, nativeFunction);

  await Future.delayed(Duration(milliseconds: 100));

  // The callback wasn't invoked, but we didn't crash either.
  Expect.equals(false, simpleFunctionResult.isCompleted);
}

NativeCallable? simpleFunctionAndCloseSelf_callable;
void simpleFunctionAndCloseSelf(int a, int b) {
  simpleFunctionAndCloseSelf_callable!.close();
  simpleFunctionResult.complete(a + b);
}

Future<void> testNativeCallableNestedCloseCall() async {
  final lib = NativeLibrary();
  simpleFunctionAndCloseSelf_callable =
      NativeCallable<CallbackNativeType>.listener(simpleFunctionAndCloseSelf);

  simpleFunctionResult = Completer<int>();
  lib.callFunctionOnSameThread(
      1000, simpleFunctionAndCloseSelf_callable!.nativeFunction);

  Expect.equals(1123, await simpleFunctionResult.future);

  // The callback is already closed.
  Expect.throwsStateError(() {
    final _ = simpleFunctionAndCloseSelf_callable!.nativeFunction;
  });
}

void simpleFunctionThrows(int a, int b) {
  throw a + b;
}

Future<void> testNativeCallableThrowInsideCallback() async {
  final lib = NativeLibrary();
  var caughtError;
  late final callback;

  runZonedGuarded(() {
    callback =
        NativeCallable<CallbackNativeType>.listener(simpleFunctionThrows);
  }, (Object error, StackTrace stack) {
    caughtError = error;
  });

  lib.callFunctionOnSameThread(1000, callback.nativeFunction);
  await Future.delayed(Duration(milliseconds: 100));

  Expect.equals(1123, caughtError);

  callback.close();
}

Future<void> testNativeCallableDontKeepAlive() async {
  final exitPort = ReceivePort();
  await Isolate.spawn((_) async {
    final lib = NativeLibrary();
    final callback =
        NativeCallable<CallbackNativeType>.listener(simpleFunction);

    simpleFunctionResult = Completer<int>();
    lib.callFunctionOnSameThread(1000, callback.nativeFunction);

    Expect.equals(1123, await simpleFunctionResult.future);
    callback.keepIsolateAlive = false;
  }, null, onExit: exitPort.sendPort);
  await exitPort.first;
  exitPort.close();
}

testNativeCallableKeepAliveGetter() {
  final callback = NativeCallable<CallbackNativeType>.listener(simpleFunction);
  Expect.isTrue(callback.keepIsolateAlive);
  callback.keepIsolateAlive = false;
  Expect.isFalse(callback.keepIsolateAlive);
  callback.keepIsolateAlive = true;
  Expect.isTrue(callback.keepIsolateAlive);
  callback.close();
}

Future<void> testNativeCallableClosure() async {
  final lib = NativeLibrary();
  int c = 70000;

  final callback = NativeCallable<CallbackNativeType>.listener((int a, int b) {
    simpleFunctionResult.complete(a + b + c);
  });

  simpleFunctionResult = Completer<int>();
  lib.callFunctionOnSameThread(1000, callback.nativeFunction);
  Expect.equals(71123, await simpleFunctionResult.future);

  c = 80000;
  simpleFunctionResult = Completer<int>();
  lib.callFunctionOnSameThread(4000, callback.nativeFunction);
  Expect.equals(84123, await simpleFunctionResult.future);

  callback.close();
}

final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");

// Global variable that is 1000 on isolate A, and 2000 on isolate B.
late final int globalVar;

class SanityCheck extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    Expect.equals(1000, globalVar);
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
    print("SanityCheck.runOnIsoA message sent. Awaiting result...");
    Expect.equals(1123, await result);
  }

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    Expect.equals(2000, globalVar);
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
    print("SanityCheck.runOnIsoB message sent. Awaiting result...");
    Expect.equals(2123, await result);
  }
}

class CallFromIsoAToIsoB extends TestCase {
  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
    print("CallFromIsoAToIsoB.runOnIsoA message sent. Awaiting result...");
    Expect.equals(2123, await result);
  }
}

class CallFromIsoBToIsoA extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
    print("CallFromIsoBToIsoA.runOnIsoB message sent. Awaiting result...");
    Expect.equals(1123, await result);
  }
}

class CallFromIsoAToIsoBViaNewThreadBlocking extends TestCase {
  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnNewThreadBlocking(
            responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
    print(
        "CallFromIsoAToIsoBViaNewThreadBlocking.runOnIsoA message sent. Awaiting result...");
    Expect.equals(2123, await result);
  }
}

class CallFromIsoBToIsoAViaNewThreadBlocking extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnNewThreadBlocking(
            responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
    print(
        "CallFromIsoBToIsoAViaNewThreadBlocking.runOnIsoB message sent. Awaiting result...");
    Expect.equals(1123, await result);
  }
}

class CallFromIsoAToIsoBViaNewThreadNonBlocking extends TestCase {
  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnNewThreadNonBlocking(
            responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
    print(
        "CallFromIsoAToIsoBViaNewThreadNonBlocking.runOnIsoA message sent. Awaiting result...");
    Expect.equals(2123, await result);
  }
}

class CallFromIsoBToIsoAViaNewThreadNonBlocking extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnNewThreadNonBlocking(
            responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
    print(
        "CallFromIsoBToIsoAViaNewThreadNonBlocking.runOnIsoB message sent. Awaiting result...");
    Expect.equals(1123, await result);
  }
}

class CallFromIsoAToBToA extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId,
            Pointer.fromAddress(
                iso.fnPtrsB.callFromIsoBToAAndMultByGlobalVarPtr)));
    print("CallFromIsoAToBToA.runOnIsoA message sent. Awaiting result...");
    Expect.equals(2000 * 1123, await result);
  }
}

class CallFromIsoBToAToB extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    final result = iso.atm.call((responseId) => iso.natLib
        .callFunctionOnSameThread(
            responseId,
            Pointer.fromAddress(
                iso.fnPtrsA.callFromIsoAToBAndMultByGlobalVarPtr)));
    print("CallFromIsoBToAToB.runOnIsoB message sent. Awaiting result...");
    Expect.equals(1000 * 2123, await result);
  }
}

class ManyCallsBetweenIsolates extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    print("ManyCallsBetweenIsolates.runOnIsoA sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnSameThread(
              responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
      Expect.equals(2123, await result);
    }));
  }

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    print("ManyCallsBetweenIsolates.runOnIsoB sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnSameThread(
              responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
      Expect.equals(1123, await result);
    }));
  }
}

class ManyCallsBetweenIsolatesViaNewThreadBlocking extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    print(
        "ManyCallsBetweenIsolatesViaNewThreadBlocking.runOnIsoA sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnNewThreadBlocking(
              responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
      Expect.equals(2123, await result);
    }));
  }

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    print(
        "ManyCallsBetweenIsolatesViaNewThreadBlocking.runOnIsoB sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnNewThreadBlocking(
              responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
      Expect.equals(1123, await result);
    }));
  }
}

class ManyCallsBetweenIsolatesViaNewThreadNonBlocking extends TestCase {
  @override
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => atm.toIsoB;

  @override
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => atm.toIsoA;

  @override
  Future<void> runOnIsoA(IsolateA iso) async {
    print(
        "ManyCallsBetweenIsolatesViaNewThreadNonBlocking.runOnIsoA sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnNewThreadNonBlocking(
              responseId, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)));
      Expect.equals(2123, await result);
    }));
  }

  @override
  Future<void> runOnIsoB(IsolateB iso) async {
    print(
        "ManyCallsBetweenIsolatesViaNewThreadNonBlocking.runOnIsoB sending messages.");
    await Future.wait(List.filled(100, null).map((_) async {
      final result = iso.atm.call((responseId) => iso.natLib
          .callFunctionOnNewThreadNonBlocking(
              responseId, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)));
      Expect.equals(1123, await result);
    }));
  }
}

class AsyncTestManager {
  int _lastResponseId = 0;
  final _pending = <int, Completer<Object>>{};
  final _recvPort = ReceivePort("AsyncTestManager");

  late final SendPort toIsoA;
  late final SendPort toIsoB;
  SendPort get toThis => _recvPort.sendPort;

  AsyncTestManager(this._lastResponseId) {
    _recvPort.listen((msg) {
      final response = msg as List;
      final id = response[0];
      final value = response[1];
      _pending[id]!.complete(value);
      _pending.remove(id);
    });
  }

  Future<Object> call(void Function(int) asyncFunc) {
    final responseId = ++_lastResponseId;
    final completer = Completer<Object>();
    _pending[responseId] = completer;
    asyncFunc(responseId);
    return completer.future;
  }

  void close() {
    _recvPort.close();
  }
}

SendPort? _callbackResultPort;

void addGlobalVar(int responseId, int x) {
  final result = x + globalVar;
  _callbackResultPort!.send([responseId, result]);
}

void callFromIsoBToAAndMultByGlobalVar(int responseIdToA, int x) {
  final iso = IsolateB.instance!;
  iso.atm
      .call((responseIdToB) => iso.natLib.callFunctionOnSameThread(
          responseIdToB, Pointer.fromAddress(iso.fnPtrsA.addGlobalVarPtr)))
      .then((response) {
    final result = (response as int) * globalVar;
    _callbackResultPort!.send([responseIdToA, result]);
  });
  print("callFromIsoBToAAndMultByGlobalVar message sent. Awaiting result...");
}

void callFromIsoAToBAndMultByGlobalVar(int responseIdToB, int x) {
  final iso = IsolateA.instance!;
  iso.atm
      .call((responseIdToA) => iso.natLib.callFunctionOnSameThread(
          responseIdToA, Pointer.fromAddress(iso.fnPtrsB.addGlobalVarPtr)))
      .then((response) {
    final result = (response as int) * globalVar;
    _callbackResultPort!.send([responseIdToB, result]);
  });
  print("callFromIsoAToBAndMultByGlobalVar message sent. Awaiting result...");
}

typedef CallbackNativeType = Void Function(Int64, Int32);

class Callbacks {
  final NativeCallable addGlobalVarFn;
  final NativeCallable callFromIsoBToAAndMultByGlobalVarFn;
  final NativeCallable callFromIsoAToBAndMultByGlobalVarFn;

  Callbacks()
      : addGlobalVarFn =
            NativeCallable<CallbackNativeType>.listener(addGlobalVar),
        callFromIsoBToAAndMultByGlobalVarFn =
            NativeCallable<CallbackNativeType>.listener(
                callFromIsoBToAAndMultByGlobalVar),
        callFromIsoAToBAndMultByGlobalVarFn =
            NativeCallable<CallbackNativeType>.listener(
                callFromIsoAToBAndMultByGlobalVar);

  void close() {
    addGlobalVarFn.close();
    callFromIsoBToAAndMultByGlobalVarFn.close();
    callFromIsoAToBAndMultByGlobalVarFn.close();
  }
}

class FnPtrs {
  // Storing function pointers as ints so they can be sent to other isolates.
  final int addGlobalVarPtr;
  final int callFromIsoBToAAndMultByGlobalVarPtr;
  final int callFromIsoAToBAndMultByGlobalVarPtr;

  FnPtrs._(this.addGlobalVarPtr, this.callFromIsoBToAAndMultByGlobalVarPtr,
      this.callFromIsoAToBAndMultByGlobalVarPtr);

  static FnPtrs fromCallbacks(Callbacks callbacks) => FnPtrs._(
        callbacks.addGlobalVarFn.nativeFunction.address,
        callbacks.callFromIsoBToAAndMultByGlobalVarFn.nativeFunction.address,
        callbacks.callFromIsoAToBAndMultByGlobalVarFn.nativeFunction.address,
      );

  static FnPtrs fromList(List<int> ptrs) => FnPtrs._(ptrs[0], ptrs[1], ptrs[2]);
  List<int> toList() => [
        addGlobalVarPtr,
        callFromIsoBToAAndMultByGlobalVarPtr,
        callFromIsoAToBAndMultByGlobalVarPtr,
      ];
}

typedef FnRunnerNativeType = Void Function(Int64, Pointer);
typedef FnRunnerType = void Function(int, Pointer);

class NativeLibrary {
  late final FnRunnerType callFunctionOnSameThread;
  late final FnRunnerType callFunctionOnNewThreadBlocking;
  late final FnRunnerType callFunctionOnNewThreadNonBlocking;

  NativeLibrary() {
    callFunctionOnSameThread =
        ffiTestFunctions.lookupFunction<FnRunnerNativeType, FnRunnerType>(
            "CallFunctionOnSameThread");
    callFunctionOnNewThreadBlocking =
        ffiTestFunctions.lookupFunction<FnRunnerNativeType, FnRunnerType>(
            "CallFunctionOnNewThreadBlocking");
    callFunctionOnNewThreadNonBlocking =
        ffiTestFunctions.lookupFunction<FnRunnerNativeType, FnRunnerType>(
            "CallFunctionOnNewThreadNonBlocking");
  }
}

class TestCase {
  SendPort? sendIsoAResultsTo(AsyncTestManager atm) => null;
  SendPort? sendIsoBResultsTo(AsyncTestManager atm) => null;
  Future<void> runOnIsoA(IsolateA isoA) async {}
  Future<void> runOnIsoB(IsolateB isoB) async {}
}

class TestCaseSendPort {
  final SendPort sendPort;
  TestCaseSendPort(this.sendPort);
}

// IsolateA is the main isolate of the test. It spawns IsolateB.
class IsolateA {
  static IsolateA? instance;
  late final SendPort sendPort;
  final recvPort = ReceivePort("Isolate A ReceivePort");
  final atm = AsyncTestManager(1000000);
  final natLib = NativeLibrary();
  final callbacksA = Callbacks();
  late final FnPtrs fnPtrsA;
  late final FnPtrs fnPtrsB;
  final bool sameGroup;

  IsolateA(this.sameGroup) {
    instance = this;
    fnPtrsA = FnPtrs.fromCallbacks(callbacksA);
    atm.toIsoA = atm.toThis;
  }

  Future<void> messageLoop() async {
    if (sameGroup) {
      await Isolate.spawn(IsolateB.entryPoint, recvPort.sendPort);
    } else {
      await Isolate.spawnUri(Platform.script, [], recvPort.sendPort);
    }
    int testIndex = 0;
    await for (final List msg in recvPort) {
      final cmd = msg[0] as String;
      final arg = msg[1];
      if (cmd == 'sendPort') {
        sendPort = arg;
        sendPort.send(['testPort', atm.toThis]);
        sendPort.send(['fnPtrs', fnPtrsA.toList()]);
      } else if (cmd == 'fnPtrs') {
        fnPtrsB = FnPtrs.fromList(arg);
      } else if (cmd == 'testPort') {
        atm.toIsoB = arg;
      } else if (cmd == 'next') {
        if (testIndex >= messagePassingTestCases.length) {
          sendPort.send(['exit', null]);
        } else {
          _callbackResultPort = null;
          sendPort.send(['testCase', testIndex]);
          final testCase = messagePassingTestCases[testIndex];
          print('\nRunning $testCase on IsoA');
          _callbackResultPort = testCase.sendIsoAResultsTo(atm);
        }
      } else if (cmd == 'run') {
        final testCase = messagePassingTestCases[testIndex];
        await testCase.runOnIsoA(this);
        print('Running $testCase on IsoA DONE\n');
        testIndex += 1;
        sendPort.send(['next', null]);
      } else if (cmd == 'exit') {
        break;
      } else {
        Expect.fail('Unknown message: $msg');
        break;
      }
    }
  }

  void close() {
    print("Closing Isolate A");
    recvPort.close();
    atm.close();
    callbacksA.close();
  }
}

// IsolateB is the secondary isolate of the test. It's spawned by IsolateA.
class IsolateB {
  static IsolateB? instance;
  final SendPort sendPort;
  final recvPort = ReceivePort("Isolate B ReceivePort");
  final atm = AsyncTestManager(2000000);
  final natLib = NativeLibrary();
  final callbacksB = Callbacks();
  late final FnPtrs fnPtrsA;
  late final FnPtrs fnPtrsB;

  IsolateB(this.sendPort) {
    instance = this;
    fnPtrsB = FnPtrs.fromCallbacks(callbacksB);
    atm.toIsoB = atm.toThis;
    sendPort.send(['sendPort', recvPort.sendPort]);
    sendPort.send(['testPort', atm.toThis]);
    sendPort.send(['fnPtrs', fnPtrsB.toList()]);
    sendPort.send(['next', null]);
  }

  Future<void> messageLoop() async {
    await for (final List msg in recvPort) {
      final cmd = msg[0] as String;
      final arg = msg[1];
      if (cmd == 'fnPtrs') {
        fnPtrsA = FnPtrs.fromList(arg);
      } else if (cmd == 'testPort') {
        atm.toIsoA = arg;
      } else if (cmd == 'testCase') {
        final testCase = messagePassingTestCases[arg];
        _callbackResultPort = testCase.sendIsoBResultsTo(atm);
        sendPort.send(['run', null]);
        print('\nRunning $testCase on IsoB');
        await testCase.runOnIsoB(this);
        print('Running $testCase on IsoB DONE\n');
      } else if (cmd == 'next') {
        _callbackResultPort = null;
        sendPort.send(['next', null]);
      } else if (cmd == 'exit') {
        sendPort.send(['exit', null]);
        break;
      } else {
        Expect.fail('Unknown message: $msg');
        break;
      }
    }
  }

  void close() {
    print("Closing Isolate B");
    recvPort.close();
    atm.close();
    callbacksB.close();
  }

  static Future<void> entryPoint(SendPort sendPort) async {
    globalVar = 2000;
    final isolateB = IsolateB(sendPort);
    await isolateB.messageLoop();
    isolateB.close();
  }
}
