// 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 = 2.9

// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--no-enable-isolate-groups

import "dart:async";
import "dart:collection";
import "dart:isolate";
import "dart:typed_data";
import "package:expect/expect.dart";

const large = 2 * 1024 * 1024;

void child(replyPort) {
  print("Child start");

  print("Child ByteData");
  dynamic x = new ByteData(large);
  for (int i = 0; i < 4; i++) {
    x.setInt8(i, i);
  }
  replyPort.send(TransferableTypedData.fromList([x.buffer.asUint8List()]));

  print("Child Uint8List");
  x = new Uint8List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Uint8List.view");
  x = new Uint8List.view(x.buffer, 1, 2);
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Int8List");
  x = new Int8List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Uint16List");
  x = new Uint16List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Int16List");
  x = new Int16List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Uint32List");
  x = new Uint32List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Int32List");
  x = new Int32List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Uint64List");
  x = new Uint64List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child Int64List");
  x = new Int64List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send(TransferableTypedData.fromList([x]));

  print("Child two Uint8Lists");
  x = new Uint8List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  replyPort.send([
    TransferableTypedData.fromList([x]),
    TransferableTypedData.fromList([x])
  ]);

  print("Child same Uint8List twice - materialize first");
  x = new Uint8List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  var tr = TransferableTypedData.fromList([x]);
  replyPort.send([tr, tr]);

  print("Child same Uint8List twice - materialize second");
  x = new Uint8List(large);
  for (int i = 0; i < 4; i++) {
    x[i] = i;
  }
  tr = TransferableTypedData.fromList([x]);
  replyPort.send([tr, tr]);

  print("Child done");
}

Future<void> main(List<String> args) async {
  print("Parent start");

  ReceivePort port = new ReceivePort();
  Isolate.spawn(child, port.sendPort);
  StreamIterator<dynamic> incoming = new StreamIterator<dynamic>(port);

  print("Parent ByteData");
  Expect.isTrue(await incoming.moveNext());
  dynamic x = incoming.current.materialize().asByteData();
  Expect.isTrue(x is ByteData);
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x.getUint8(i));
  }

  print("Parent Uint8List");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize();
  Expect.isTrue(x is ByteBuffer);
  x = x.asUint8List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Uint8List view");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asUint8List();
  Expect.equals(1, x[0]);
  Expect.equals(2, x[1]);

  print("Parent Int8");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asInt8List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Uint16");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asUint16List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Int16");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asInt16List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Uint32");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asUint32List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Int32");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asInt32List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Uint64");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asUint64List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent Int64");
  Expect.isTrue(await incoming.moveNext());
  x = incoming.current.materialize().asInt64List();
  Expect.equals(large, x.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x[i]);
  }

  print("Parent two Uint8Lists");
  Expect.isTrue(await incoming.moveNext());
  final x1 = incoming.current[0].materialize().asUint8List();
  final x2 = incoming.current[1].materialize().asUint8List();
  Expect.equals(large, x1.length);
  Expect.equals(large, x2.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, x1[i]);
    Expect.equals(i, x2[i]);
  }

  print("Parent same Uint8Lists twice, materialize first");
  Expect.isTrue(await incoming.moveNext());
  final tr0 = incoming.current[0].materialize().asUint8List();
  Expect.throwsArgumentError(() => incoming.current[1].materialize());
  Expect.equals(large, tr0.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, tr0[i]);
  }

  print("Parent same Uint8Lists twice, materialize second");
  Expect.isTrue(await incoming.moveNext());
  final tr1 = incoming.current[1].materialize().asUint8List();
  Expect.throwsArgumentError(() => incoming.current[0].materialize());
  Expect.equals(large, tr1.length);
  for (int i = 0; i < 4; i++) {
    Expect.equals(i, tr1[i]);
  }

  port.close();
  print("Parent done");

  testCreateMaterializeInSameIsolate();
  testIterableToList();
  testUserExtendedList();
}

testCreateMaterializeInSameIsolate() {
  // Test same-isolate operation of TransferableTypedData.
  final Uint8List bytes = new Uint8List(large);
  for (int i = 0; i < bytes.length; ++i) {
    bytes[i] = i % 256;
  }
  final tr = TransferableTypedData.fromList([bytes]);
  Expect.listEquals(bytes, tr.materialize().asUint8List());
}

testIterableToList() {
  // Test that iterable.toList() can be used as an argument.
  final list1 = Uint8List(10);
  for (int i = 0; i < list1.length; i++) {
    list1[i] = i;
  }
  final list2 = Uint8List(20);
  for (int i = 0; i < list2.length; i++) {
    list2[i] = i + list1.length;
  }
  final map = {list1: true, list2: true};
  Iterable<Uint8List> iterable = map.keys;
  final result = TransferableTypedData.fromList(iterable.toList())
      .materialize()
      .asUint8List();
  for (int i = 0; i < result.length; i++) {
    Expect.equals(i, result[i]);
  }
}

class MyList<E> extends ListBase<E> {
  List<E> _source;
  MyList(this._source);
  int get length => _source.length;
  void set length(int length) {
    _source.length = length;
  }

  E operator [](int index) => _source[index];
  void operator []=(int index, E value) {
    _source[index] = value;
  }
}

testUserExtendedList() {
  final list = MyList<TypedData>([Uint8List(10)]);
  TransferableTypedData.fromList(list);
}
