// Copyright (c) 2019, 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 function pointers with struct
// arguments.
//
// SharedObjects=ffi_test_functions

// @dart = 2.9

import 'dart:ffi';

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

import 'coordinate.dart';
import 'dylib_utils.dart';
import 'very_large_struct.dart';

typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);

void main() {
  testFunctionWithStruct();
  testFunctionWithStructArray();
  testFunctionWithVeryLargeStruct();
}

DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");

/// pass a struct to a c function and get a struct as return value
void testFunctionWithStruct() {
  Pointer<NativeFunction<NativeCoordinateOp>> p1 =
      ffiTestFunctions.lookup("TransposeCoordinate");
  NativeCoordinateOp f1 = p1.asFunction();

  final c1 = calloc<Coordinate>()
    ..ref.x = 10.0
    ..ref.y = 20.0;
  final c2 = calloc<Coordinate>()
    ..ref.x = 42.0
    ..ref.y = 84.0
    ..ref.next = c1;
  c1.ref.next = c2;

  Coordinate result = f1(c1).ref;

  Expect.approxEquals(20.0, c1.ref.x);
  Expect.approxEquals(30.0, c1.ref.y);

  Expect.approxEquals(42.0, result.x);
  Expect.approxEquals(84.0, result.y);

  calloc.free(c1);
  calloc.free(c2);
}

/// pass an array of structs to a c funtion
void testFunctionWithStructArray() {
  Pointer<NativeFunction<NativeCoordinateOp>> p1 =
      ffiTestFunctions.lookup("CoordinateElemAt1");
  NativeCoordinateOp f1 = p1.asFunction();

  final coordinateArray = calloc<Coordinate>(3);
  Coordinate c1 = coordinateArray[0];
  Coordinate c2 = coordinateArray[1];
  Coordinate c3 = coordinateArray[2];
  c1.x = 10.0;
  c1.y = 10.0;
  c1.next = coordinateArray.elementAt(2);
  c2.x = 20.0;
  c2.y = 20.0;
  c2.next = coordinateArray.elementAt(0);
  c3.x = 30.0;
  c3.y = 30.0;
  c3.next = coordinateArray.elementAt(1);

  Coordinate result = f1(coordinateArray.elementAt(0)).ref;
  Expect.approxEquals(20.0, result.x);
  Expect.approxEquals(20.0, result.y);

  calloc.free(coordinateArray);
}

typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
typedef NativeVeryLargeStructSum = Int64 Function(Pointer<VeryLargeStruct>);

void testFunctionWithVeryLargeStruct() {
  Pointer<NativeFunction<NativeVeryLargeStructSum>> p1 =
      ffiTestFunctions.lookup("SumVeryLargeStruct");
  VeryLargeStructSum f = p1.asFunction();

  final vlsArray = calloc<VeryLargeStruct>(2);
  VeryLargeStruct vls1 = vlsArray[0];
  VeryLargeStruct vls2 = vlsArray[1];
  List<VeryLargeStruct> structs = [vls1, vls2];
  for (VeryLargeStruct struct in structs) {
    struct.a = 1;
    struct.b = 2;
    struct.c = 4;
    struct.d = 8;
    struct.e = 16;
    struct.f = 32;
    struct.g = 64;
    struct.h = 128;
    struct.i = 256;
    struct.j = 512;
    struct.k = 1024;
    struct.smallLastField = 1;
  }
  vls1.parent = vlsArray.elementAt(1);
  vls1.numChildren = 2;
  vls1.children = vlsArray.elementAt(0);
  vls2.parent = vlsArray.elementAt(1);
  vls2.parent = nullptr;
  vls2.numChildren = 0;
  vls2.children = nullptr;

  int result = f(vlsArray.elementAt(0));
  Expect.equals(2051, result);

  result = f(vlsArray.elementAt(1));
  Expect.equals(2048, result);

  calloc.free(vlsArray);
}
