// 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.
//
// Tests the sizes of c types from https://dartbug.com/36140.
//
// SharedObjects=ffi_test_functions

// @dart = 2.9

import 'dart:ffi';
import 'dart:io' show Platform;

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

import 'ffi_test_helpers.dart';

void main() {
  printSizes();
  testSizes();
  testIntAssumptions();
  testSizeTAssumptions();
  testLongAssumptions();
  testWCharTAssumptions();
}

class CType {
  final int ffiSize;
  final int Function(Pointer) ffiLoad;
  final String modifier;
  final String type;
  final String type2;

  CType(this.ffiSize, this.type,
      {this.type2 = '', this.modifier = '', this.ffiLoad});

  String get cRepresentation => '$modifier $type $type2'.trim();

  String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';

  String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';

  int Function() get sizeFunction => ffiTestFunctions
      .lookupFunction<Uint64 Function(), int Function()>(_getSizeName);

  int Function() get signFunction => ffiTestFunctions
      .lookupFunction<Uint64 Function(), int Function()>(_getSignName);

  int get size => sizeFunction();

  bool get isSigned => signFunction() != 0;

  bool get ffiIsSigned {
    final ffiLoad_ = ffiLoad;
    if (ffiLoad_ == null) {
      return null;
    }
    assert(size < 8);
    return using((Arena arena) {
      final p = arena<Int64>()..value = -1;
      return ffiLoad_(p) < 0;
    });
  }

  String toString() => cRepresentation;
}

final char = CType(
  sizeOf<Char>(),
  'char',
  ffiLoad: (Pointer p) => p.cast<Char>().value,
);
final uchar = CType(
  sizeOf<UnsignedChar>(),
  'char',
  modifier: 'unsigned',
  ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
);
final schar = CType(
  sizeOf<SignedChar>(),
  'char',
  modifier: 'signed',
  ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
);
final short = CType(
  sizeOf<Short>(),
  'short',
  ffiLoad: (Pointer p) => p.cast<Short>().value,
);
final ushort = CType(
  sizeOf<UnsignedShort>(),
  'short',
  modifier: 'unsigned',
  ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
);
final int_ = CType(
  sizeOf<Int>(),
  'int',
  ffiLoad: (Pointer p) => p.cast<Int>().value,
);
final uint = CType(
  sizeOf<UnsignedInt>(),
  'int',
  modifier: 'unsigned',
  ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
);
final long = CType(
  sizeOf<Long>(),
  'long',
);
final ulong = CType(
  sizeOf<UnsignedLong>(),
  'long',
  modifier: 'unsigned',
);
final longlong = CType(
  sizeOf<LongLong>(),
  'long',
  type2: 'long',
);
final ulonglong = CType(
  sizeOf<UnsignedLongLong>(),
  'long',
  type2: 'long',
  modifier: 'unsigned',
);
final intptr_t = CType(
  sizeOf<IntPtr>(),
  'intptr_t',
);
final uintptr_t = CType(
  sizeOf<UintPtr>(),
  'uintptr_t',
);
final size_t = CType(
  sizeOf<Size>(),
  'size_t',
);
final wchar_t = CType(
  sizeOf<WChar>(),
  'wchar_t',
  ffiLoad: (Pointer p) => p.cast<WChar>().value,
);

final cTypes = [
  char,
  uchar,
  schar,
  short,
  ushort,
  int_,
  uint,
  long,
  ulong,
  longlong,
  ulonglong,
  intptr_t,
  uintptr_t,
  size_t,
  wchar_t,
];

void printSizes() {
  cTypes.forEach((element) {
    final cName = element.cRepresentation.padRight(20);
    final size = element.size;
    final signed = element.isSigned ? 'signed' : 'unsigned';
    print('$cName: $size $signed');
  });
}

void testSizes() {
  cTypes.forEach((element) {
    print(element);
    Expect.equals(element.size, element.ffiSize);
    final ffiIsSigned = element.ffiIsSigned;
    if (ffiIsSigned != null) {
      Expect.equals(element.isSigned, ffiIsSigned);
    }
  });
}

void testIntAssumptions() {
  Expect.equals(4, int_.size);
  Expect.equals(4, uint.size);
}

void testSizeTAssumptions() {
  Expect.equals(intptr_t.size, size_t.size);
}

void testLongAssumptions() {
  if (Platform.isWindows) {
    Expect.equals(4, long.size);
    Expect.equals(4, ulong.size);
  } else {
    Expect.equals(intptr_t.size, long.size);
    Expect.equals(intptr_t.size, ulong.size);
  }
}

void testWCharTAssumptions() {
  final bool isSigned = wchar_t.isSigned;
  print('wchar_t isSigned $isSigned');
  if (Platform.isWindows) {
    Expect.equals(2, wchar_t.size);
    if (isSigned) {
      Expect.equals(-0x8000, wCharMinValue());
      Expect.equals(0x7fff, wCharMaxValue());
    } else {
      Expect.equals(0, wCharMinValue());
      Expect.equals(0xffff, wCharMaxValue());
    }
  } else {
    Expect.equals(4, wchar_t.size);
    if (isSigned) {
      Expect.equals(-0x80000000, wCharMinValue());
      Expect.equals(0x7fffffff, wCharMaxValue());
    } else {
      Expect.equals(0, wCharMinValue());
      Expect.equals(0xffffffff, wCharMaxValue());
    }
  }
}

int Function() wCharMinValue = ffiTestFunctions
    .lookupFunction<Uint64 Function(), int Function()>('WCharMinValue');

int Function() wCharMaxValue = ffiTestFunctions
    .lookupFunction<Uint64 Function(), int Function()>('WCharMaxValue');
