// Copyright (c) 2020, 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.
//
// SharedObjects=ffi_test_functions

// @dart = 2.9

import 'dart:ffi';

import 'package:expect/expect.dart';

import 'dylib_utils.dart';

void main() {
  testHandle();
  testReadField();
  testTrueHandle();
  testClosureCallback();
  testReturnHandleInCallback();
  testPropagateError();
  testCallbackReturnException();
  testDeepException();
  testDeepException2();
  testNull();
  testDeepRecursive();
  testNoHandlePropagateError();
}

void testHandle() {
  print("testHandle");
  final s = SomeClass(123);
  print("passObjectToC($s)");
  final result = passObjectToC(s);
  print("result = $result");
  Expect.isTrue(identical(s, result));
}

void testReadField() {
  final s = SomeClass(123);
  final result = handleReadFieldValue(s);
  Expect.equals(s.a, result);
}

void testTrueHandle() {
  final result = trueHandle();
  Expect.isTrue(result);
}

int globalCounter = 0;

void increaseCounter() {
  print("increaseCounter");
  globalCounter++;
}

void doClosureCallback(Object callback) {
  print("doClosureCallback");
  print(callback.runtimeType);
  print(callback);
  final callback_as_function = callback as void Function();
  callback_as_function();
}

final closureCallbackPointer =
    Pointer.fromFunction<Void Function(Handle)>(doClosureCallback);

void testClosureCallback() {
  print("testClosureCallback $closureCallbackPointer");
  Expect.equals(0, globalCounter);
  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
  Expect.equals(1, globalCounter);
  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
  Expect.equals(2, globalCounter);
}

final someObject = SomeClass(12356789);

Object returnHandleCallback() {
  print("returnHandleCallback returning $someObject");
  return someObject;
}

final returnHandleCallbackPointer =
    Pointer.fromFunction<Handle Function()>(returnHandleCallback);

void testReturnHandleInCallback() {
  print("testReturnHandleInCallback");
  final result = returnHandleInCallback(returnHandleCallbackPointer);
  Expect.isTrue(identical(someObject, result));
}

class SomeClass {
  // We use this getter in the native api, don't tree shake it.
  @pragma("vm:entry-point")
  final int a;
  SomeClass(this.a);
}

void testPropagateError() {
  final s = SomeOtherClass(123);
  Expect.throws(() => handleReadFieldValue(s));
}

class SomeOtherClass {
  final int notA;
  SomeOtherClass(this.notA);
}

final someException = Exception("exceptionHandleCallback exception");

Object exceptionHandleCallback() {
  print("exceptionHandleCallback throwing ($someException)");
  throw someException;
}

final exceptionHandleCallbackPointer =
    Pointer.fromFunction<Handle Function()>(exceptionHandleCallback);

void testCallbackReturnException() {
  print("testCallbackReturnException");
  bool throws = false;
  try {
    final result = returnHandleInCallback(exceptionHandleCallbackPointer);
    print(result);
  } catch (e) {
    throws = true;
    print("caught ($e)");
    Expect.isTrue(identical(someException, e));
  }
  Expect.isTrue(throws);
}

Object callCAgainFromCallback() {
  print("callCAgainFromCallback");
  final s = SomeOtherClass(123);
  Expect.throws(() => handleReadFieldValue(s));
  return someObject;
}

final callCAgainFromCallbackPointer =
    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback);

void testDeepException() {
  print("testDeepException");
  final result = returnHandleInCallback(callCAgainFromCallbackPointer);
  Expect.isTrue(identical(someObject, result));
}

Object callCAgainFromCallback2() {
  print("callCAgainFromCallback2");
  final s = SomeOtherClass(123);
  handleReadFieldValue(s); // throws.
  return someObject;
}

final callCAgainFromCallbackPointer2 =
    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback2);

void testDeepException2() {
  print("testDeepException2");
  Expect.throws(() => returnHandleInCallback(callCAgainFromCallbackPointer2));
}

Object returnNullHandleCallback() {
  print("returnHandleCallback returning null");
  return null;
}

final returnNullHandleCallbackPointer =
    Pointer.fromFunction<Handle Function()>(returnNullHandleCallback);

void testNull() {
  print("testNull");
  final result = passObjectToC(null);
  Expect.isNull(result);

  final result2 = returnHandleInCallback(returnNullHandleCallbackPointer);
  Expect.isNull(result2);
}

Object recurseAbove0(int i) {
  print("recurseAbove0($i)");
  if (i == 0) {
    print("throwing");
    throw someException;
  }
  if (i < 0) {
    print("returning");
    return someObject;
  }
  final result =
      handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, i - 1);
  print("return $i");
  return result;
}

final recurseAbove0Pointer =
    Pointer.fromFunction<Handle Function(Int64)>(recurseAbove0);

class SomeClassWithMethod {
  // We use this method in the native api, don't tree shake it.
  @pragma("vm:entry-point")
  Object a(int i) => recurseAbove0(i);
}

void testDeepRecursive() {
  // works on arm.
  Expect.throws(() {
    handleRecursion(123, recurseAbove0Pointer, 1);
  });

  Expect.throws(() {
    handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, 1);
  });

  Expect.throws(() {
    recurseAbove0(100);
  });

  final result = recurseAbove0(101);
  Expect.isTrue(identical(someObject, result));
}

void testNoHandlePropagateError() {
  bool throws = false;
  try {
    final result = propagateErrorWithoutHandle(exceptionHandleCallbackPointer);
    print(result);
  } catch (e) {
    throws = true;
    print("caught ($e)");
    Expect.isTrue(identical(someException, e));
  }
  Expect.isTrue(throws);
}

final testLibrary = dlopenPlatformSpecific("ffi_test_functions");

final passObjectToC = testLibrary.lookupFunction<Handle Function(Handle),
    Object Function(Object)>("PassObjectToC");

final handleReadFieldValue =
    testLibrary.lookupFunction<Int64 Function(Handle), int Function(Object)>(
        "HandleReadFieldValue");

final trueHandle = testLibrary
    .lookupFunction<Handle Function(), Object Function()>("TrueHandle");

final closureCallbackThroughHandle = testLibrary.lookupFunction<
    Void Function(Pointer<NativeFunction<Void Function(Handle)>>, Handle),
    void Function(Pointer<NativeFunction<Void Function(Handle)>>,
        Object)>("ClosureCallbackThroughHandle");

final returnHandleInCallback = testLibrary.lookupFunction<
    Handle Function(Pointer<NativeFunction<Handle Function()>>),
    Object Function(
        Pointer<NativeFunction<Handle Function()>>)>("ReturnHandleInCallback");

final handleRecursion = testLibrary.lookupFunction<
    Handle Function(
        Handle, Pointer<NativeFunction<Handle Function(Int64)>>, Int64),
    Object Function(Object, Pointer<NativeFunction<Handle Function(Int64)>>,
        int)>("HandleRecursion");

final propagateErrorWithoutHandle = testLibrary.lookupFunction<
        Int64 Function(Pointer<NativeFunction<Handle Function()>>),
        int Function(Pointer<NativeFunction<Handle Function()>>)>(
    "PropagateErrorWithoutHandle");
