// 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
//
// VMOptions=--deterministic --optimization-counter-threshold=90 --use-slow-path --stacktrace-every=100

import 'dart:ffi';

import "package:expect/expect.dart";
import "package:ffi/ffi.dart";

import 'dylib_utils.dart';

// Reuse the struct classes.
import 'function_structs_by_value_generated_compounds.dart';

final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");

void main() {
  for (int i = 0; i < 100; i++) {
    recursiveTest(10);
    recursiveTest(11);
    testCopyLogic();
  }
}

void recursiveTest(int recursionCounter) {
  final pointer = calloc<Struct20BytesHomogeneousInt32>();
  final struct = pointer.ref;
  struct.a0 = 1;
  struct.a1 = 2;
  struct.a2 = 3;
  struct.a3 = 4;
  struct.a4 = 5;
  final result = dartPassStructRecursive(recursionCounter, struct);
  Expect.equals(struct.a0 + recursionCounter * 2, result.a0);
  Expect.equals(struct.a1, result.a1);
  Expect.equals(struct.a2, result.a2);
  Expect.equals(struct.a3, result.a3);
  Expect.equals(struct.a4, result.a4);
  calloc.free(pointer);
}

Struct20BytesHomogeneousInt32 dartPassStructRecursive(
  int recursionCounter,
  Struct20BytesHomogeneousInt32 struct,
) {
  print("callbackPassStructRecursive($recursionCounter, $struct)");
  struct.a0++;
  final structA0Saved = struct.a0;
  if (recursionCounter <= 0) {
    print("returning");
    return struct;
  }

  final result = cPassStructRecursive(
    recursionCounter - 1,
    struct,
    functionPointer,
  );
  result.a0++;

  // Check struct.a0 is not modified by Dart->C call.
  Expect.equals(structA0Saved, struct.a0);

  // Check struct.a0 is not modified by C->Dart callback, if so struct.a4 == 0.
  Expect.notEquals(0, struct.a4);

  return result;
}

final functionPointer =
    Pointer.fromFunction<
      Struct20BytesHomogeneousInt32 Function(
        Int64,
        Struct20BytesHomogeneousInt32,
      )
    >(dartPassStructRecursive);

final cPassStructRecursive = ffiTestFunctions
    .lookupFunction<
      Struct20BytesHomogeneousInt32 Function(
        Int64 recursionCounter,
        Struct20BytesHomogeneousInt32 struct,
        Pointer callbackAddress,
      ),
      Struct20BytesHomogeneousInt32 Function(
        int recursionCounter,
        Struct20BytesHomogeneousInt32,
        Pointer,
      )
    >("PassStructRecursive");

Struct8BytesNestedInt typedDataBackedStruct =
    Pointer<Struct8BytesNestedInt>.fromAddress(0).ref;
bool typedDataBackedStructSet = false;
void _receiveStructByValue(Struct8BytesNestedInt struct) {
  typedDataBackedStruct = struct;
  typedDataBackedStructSet = true;
}

final _receiveStructByValuePointer =
    Pointer.fromFunction<Void Function(Struct8BytesNestedInt)>(
      _receiveStructByValue,
    );

final _invokeReceiveStructByValue = ffiTestFunctions
    .lookupFunction<
      Void Function(
        Pointer<NativeFunction<Void Function(Struct8BytesNestedInt)>>,
      ),
      void Function(
        Pointer<NativeFunction<Void Function(Struct8BytesNestedInt)>>,
      )
    >("CallbackWithStruct");

void testCopyLogic() {
  _invokeReceiveStructByValue(_receiveStructByValuePointer);
  Expect.isTrue(typedDataBackedStructSet);

  final pointer = calloc<Struct8BytesNestedInt>();
  final pointerBackedStruct = pointer.ref;

  void reset() {
    pointerBackedStruct.a0.a0 = 1;
    pointerBackedStruct.a0.a1 = 2;
    pointerBackedStruct.a1.a0 = 3;
    pointerBackedStruct.a1.a1 = 4;
    typedDataBackedStruct.a0.a0 = 5;
    typedDataBackedStruct.a0.a1 = 6;
    typedDataBackedStruct.a1.a0 = 7;
    typedDataBackedStruct.a1.a1 = 8;
  }

  // Pointer -> Pointer.
  reset();
  pointerBackedStruct.a1 = pointerBackedStruct.a0;
  Expect.equals(1, pointerBackedStruct.a1.a0);
  Expect.equals(2, pointerBackedStruct.a1.a1);

  // Pointer -> TypedData.
  reset();
  typedDataBackedStruct.a1 = pointerBackedStruct.a0;
  Expect.equals(1, typedDataBackedStruct.a1.a0);
  Expect.equals(2, typedDataBackedStruct.a1.a1);

  // TypedData -> Pointer.
  reset();
  pointerBackedStruct.a1 = typedDataBackedStruct.a0;
  Expect.equals(5, pointerBackedStruct.a1.a0);
  Expect.equals(6, pointerBackedStruct.a1.a1);

  // TypedData -> TypedData.
  reset();
  typedDataBackedStruct.a1 = typedDataBackedStruct.a0;
  Expect.equals(5, typedDataBackedStruct.a1.a0);
  Expect.equals(6, typedDataBackedStruct.a1.a1);

  calloc.free(pointer);
}
