// Copyright (c) 2021, 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 = 2.9

// SharedObjects=ffi_test_functions

import 'dart:ffi';

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

// We want at least 1 mapping to satisfy the static checks.
const notTestingOn = Abi.fuchsiaArm64;

@AbiSpecificIntegerMapping({
  notTestingOn: Int8(),
})
class Incomplete extends AbiSpecificInteger {
  const Incomplete();
}

void main() {
  if (Abi.current() == notTestingOn) {
    return;
  }
  testSizeOf();
  testStoreLoad();
  testStoreLoadIndexed();
  testStruct();
  testInlineArray();
  testInlineArray2();
  testAsFunction();
  testFromFunction();
}

void testSizeOf() {
  Expect.throws(() {
    sizeOf<Incomplete>();
  });
}

void testStoreLoad() {
  final p = calloc<Int64>().cast<Incomplete>();
  Expect.throws(() {
    p.value = 10;
  });
  Expect.throws(() {
    p.value;
  });
  calloc.free(p);
}

void testStoreLoadIndexed() {
  final p = calloc<Int64>().cast<Incomplete>();
  Expect.throws(() {
    p[0] = 10;
  });
  Expect.throws(() {
    p[1];
  });
  calloc.free(p);
}

class IncompleteStruct extends Struct {
  @Incomplete()
  int a0;

  @Incomplete()
  int a1;
}

void testStruct() {
  final p = calloc<Int64>(2).cast<IncompleteStruct>();
  Expect.throws(() {
    p.ref.a0 = 1;
  });
  Expect.throws(() {
    p.ref.a0;
  });
  calloc.free(p);
}

class IncompleteArrayStruct extends Struct {
  @Array(100)
  Array<Incomplete> a0;
}

void testInlineArray() {
  final p = calloc<Int64>(100).cast<IncompleteArrayStruct>();
  final array = p.ref.a0;
  Expect.throws(() {
    array[3] = 4;
  });
  Expect.throws(() {
    array[3];
  });
  calloc.free(p);
}

const _dim1 = 8;
const _dim2 = 4;

class IncompleteArrayArrayStruct extends Struct {
  @Array(_dim1, _dim2)
  Array<Array<Incomplete>> a0;
}

void testInlineArray2() {
  final p = calloc<Int64>(100).cast<IncompleteArrayArrayStruct>();
  Expect.throws(() {
    p.elementAt(3);
  });
  calloc.free(p);
}

void testAsFunction() {
  Expect.throws(() {
    nullptr
        .cast<NativeFunction<Int32 Function(Incomplete)>>()
        .asFunction<int Function(int)>();
  });
  Expect.throws(() {
    nullptr
        .cast<NativeFunction<Incomplete Function(Int32)>>()
        .asFunction<int Function(int)>();
  });
  Expect.throws(() {
    nullptr
        .cast<NativeFunction<Int32 Function(IncompleteArrayStruct)>>()
        .asFunction<int Function(IncompleteArrayStruct)>();
  });
  Expect.throws(() {
    nullptr
        .cast<NativeFunction<IncompleteArrayStruct Function()>>()
        .asFunction<IncompleteArrayStruct Function()>();
  });
}

int myIncr(int a) => a + 1;

IncompleteArrayStruct myIncompleteReturn() =>
    nullptr.cast<IncompleteArrayStruct>().ref;

int myIncompleteArg(IncompleteArrayStruct a) => 5;

void testFromFunction() {
  Expect.throws(() {
    Pointer.fromFunction<Incomplete Function(Int32)>(myIncr, 3);
  });
  Expect.throws(() {
    Pointer.fromFunction<Int32 Function(Incomplete)>(myIncr, 3);
  });
  Expect.throws(() {
    Pointer.fromFunction<IncompleteArrayStruct Function()>(myIncompleteReturn);
  });
  Expect.throws(() {
    Pointer.fromFunction<Int32 Function(IncompleteArrayStruct)>(
        myIncompleteArg, 3);
  });
}
