// 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 struct pointers.
//
// VMOptions=--deterministic --optimization-counter-threshold=50

import 'dart:ffi';

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

import 'calloc.dart';
import 'coordinate_bare.dart' as bare;
import 'coordinate.dart';
import 'ffi_test_helpers.dart';

void main() {
  for (int i = 0; i < 100; i++) {
    testStructAllocate();
    testStructFromAddress();
    testStructWithNulls();
    testBareStruct();
    testTypeTest();
    testUtf8();
  }
}

/// allocates each coordinate separately in c memory
void testStructAllocate() {
  Pointer<Coordinate> c1 =
      Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
  Pointer<Coordinate> c2 =
      Coordinate.allocate(calloc, 20.0, 20.0, c1).addressOf;
  Pointer<Coordinate> c3 =
      Coordinate.allocate(calloc, 30.0, 30.0, c2).addressOf;
  c1.ref.next = c3;

  Coordinate currentCoordinate = c1.ref;
  Expect.equals(10.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(30.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(20.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(10.0, currentCoordinate.x);

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

/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
  Pointer<Coordinate> c1 = calloc(3);
  Pointer<Coordinate> c2 = c1.elementAt(1);
  Pointer<Coordinate> c3 = c1.elementAt(2);
  c1.ref
    ..x = 10.0
    ..y = 10.0
    ..next = c3;
  c2.ref
    ..x = 20.0
    ..y = 20.0
    ..next = c1;
  c3.ref
    ..x = 30.0
    ..y = 30.0
    ..next = c2;

  Coordinate currentCoordinate = c1.ref;
  Expect.equals(10.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(30.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(20.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(10.0, currentCoordinate.x);

  calloc.free(c1);
}

void testStructWithNulls() {
  Pointer<Coordinate> coordinate =
      Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
  Expect.equals(coordinate.ref.next, nullptr);
  coordinate.ref.next = coordinate;
  Expect.notEquals(coordinate.ref.next, nullptr);
  coordinate.ref.next = nullptr;
  Expect.equals(coordinate.ref.next, nullptr);
  calloc.free(coordinate);
}

void testBareStruct() {
  int structSize = sizeOf<Double>() * 2 + sizeOf<IntPtr>();
  bare.Coordinate c1 =
      calloc<Uint8>(structSize * 3).cast<bare.Coordinate>().ref;
  bare.Coordinate c2 =
      c1.addressOf.offsetBy(structSize).cast<bare.Coordinate>().ref;
  bare.Coordinate c3 =
      c1.addressOf.offsetBy(structSize * 2).cast<bare.Coordinate>().ref;
  c1.x = 10.0;
  c1.y = 10.0;
  c1.next = c3.addressOf;
  c2.x = 20.0;
  c2.y = 20.0;
  c2.next = c1.addressOf;
  c3.x = 30.0;
  c3.y = 30.0;
  c3.next = c2.addressOf;

  bare.Coordinate currentCoordinate = c1;
  Expect.equals(10.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(30.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(20.0, currentCoordinate.x);
  currentCoordinate = currentCoordinate.next.ref;
  Expect.equals(10.0, currentCoordinate.x);

  calloc.free(c1.addressOf);
}

void testTypeTest() {
  Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
  Expect.isTrue(c is Struct);
  Expect.isTrue(c.addressOf is Pointer<Coordinate>);
  calloc.free(c.addressOf);
}

void testUtf8() {
  final String test = 'Hasta Mañana';
  final Pointer<Utf8> medium = Utf8.toUtf8(test);
  Expect.equals(test, Utf8.fromUtf8(medium));
  calloc.free(medium);
}
