// 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=--stacktrace-every=100
// 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 "package:expect/expect.dart";

import 'dylib_utils.dart';

main(args, message) async {
  testNativeCallableStatic();
  testNativeCallableClosure();
  testNativeCallableDoubleCloseError();
  testNativeCallableNestedCloseCallStatic();
  testNativeCallableNestedCloseCallClosure();
  testNativeCallableExceptionalReturnStatic();
  testNativeCallableExceptionalReturnClosure();
  await testNativeCallableDontKeepAliveStatic();
  await testNativeCallableDontKeepAliveClosure();
  testNativeCallableKeepAliveGetter();
  print("All tests completed :)");
}

final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");

typedef TwoIntFnNativeType = Int32 Function(Pointer, Int32, Int32);
typedef TwoIntFnType = int Function(Pointer, int, int);
final callTwoIntFunction = ffiTestFunctions
    .lookupFunction<TwoIntFnNativeType, TwoIntFnType>("CallTwoIntFunction");

typedef CallbackNativeType = Int32 Function(Int32, Int32);
int add(int a, int b) {
  return a + b;
}

testNativeCallableStatic() {
  final callback = NativeCallable<CallbackNativeType>.isolateLocal(add,
      exceptionalReturn: 0);

  Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

  callback.close();
}

testNativeCallableClosure() {
  int c = 70000;

  final callback = NativeCallable<CallbackNativeType>.isolateLocal(
      (int a, int b) => a + b + c,
      exceptionalReturn: 0);

  Expect.equals(71234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

  c = 80000;
  Expect.equals(81234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

  callback.close();
}

testNativeCallableDoubleCloseError() {
  final callback = NativeCallable<CallbackNativeType>.isolateLocal(add,
      exceptionalReturn: 0);
  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);
}

late NativeCallable selfClosingStaticCallback;
int selfClosingStatic(int a, int b) {
  selfClosingStaticCallback.close();
  return a + b;
}

testNativeCallableNestedCloseCallStatic() {
  selfClosingStaticCallback = NativeCallable<CallbackNativeType>.isolateLocal(
      selfClosingStatic,
      exceptionalReturn: 0);

  Expect.equals(1234,
      callTwoIntFunction(selfClosingStaticCallback.nativeFunction, 1000, 234));

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

testNativeCallableNestedCloseCallClosure() {
  late NativeCallable callback;

  callback = NativeCallable<CallbackNativeType>.isolateLocal((int a, int b) {
    callback.close();
    return a + b;
  }, exceptionalReturn: 0);

  Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

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

int throwerCallback(int a, int b) {
  if (a != 1000) {
    throw "Oh no!";
  }
  return a + b;
}

testNativeCallableExceptionalReturnStatic() {
  final callback = NativeCallable<CallbackNativeType>.isolateLocal(
      throwerCallback,
      exceptionalReturn: 5678);

  Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));
  Expect.equals(5678, callTwoIntFunction(callback.nativeFunction, 0, 0));

  callback.close();
}

testNativeCallableExceptionalReturnClosure() {
  final callback =
      NativeCallable<CallbackNativeType>.isolateLocal((int a, int b) {
    if (a != 1000) {
      throw "Oh no!";
    }
    return a + b;
  }, exceptionalReturn: 5678);

  Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));
  Expect.equals(5678, callTwoIntFunction(callback.nativeFunction, 0, 0));

  callback.close();
}

Future<void> testNativeCallableDontKeepAliveStatic() async {
  final exitPort = ReceivePort();
  await Isolate.spawn((_) async {
    final callback = NativeCallable<CallbackNativeType>.isolateLocal(add,
        exceptionalReturn: 0);

    Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

    callback.keepIsolateAlive = false;
  }, null, onExit: exitPort.sendPort);
  await exitPort.first;
  exitPort.close();
}

Future<void> testNativeCallableDontKeepAliveClosure() async {
  int c = 70000;

  final exitPort = ReceivePort();
  await Isolate.spawn((_) async {
    final callback = NativeCallable<CallbackNativeType>.isolateLocal(
        (int a, int b) => a + b + c,
        exceptionalReturn: 0);

    Expect.equals(
        71234, callTwoIntFunction(callback.nativeFunction, 1000, 234));

    callback.keepIsolateAlive = false;
  }, null, onExit: exitPort.sendPort);
  await exitPort.first;
  exitPort.close();
}

testNativeCallableKeepAliveGetter() {
  final callback = NativeCallable<CallbackNativeType>.isolateLocal(add,
      exceptionalReturn: 0);
  // Check that only the flag changes are counted by decrementing and
  // incrementing a lot, and by different amounts.
  for (int i = 0; i < 100; ++i) {
    callback.keepIsolateAlive = false;
    Expect.isFalse(callback.keepIsolateAlive);
  }
  for (int i = 0; i < 200; ++i) {
    callback.keepIsolateAlive = true;
    Expect.isTrue(callback.keepIsolateAlive);
  }
  callback.close();
}
