// 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.

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

// Test that validates that transferables are faster than regular typed data.

import 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';

import "package:expect/expect.dart";

const int toIsolateSize = 100 * 1024 * 1024;
const int fromIsolateSize = 100 * 1024 * 1024;

const int nIterations = 5;

int iteration = -1;
bool keepTimerRunning = false;

main() async {
  keepTimerRunning = true;

  print('--- standard');
  iteration = nIterations;
  final stopwatch = new Stopwatch()..start();
  await runBatch(useTransferable: false);
  final standard = stopwatch.elapsedMilliseconds;

  print('--- transferable');
  iteration = nIterations;
  stopwatch.reset();
  await runBatch(useTransferable: true);
  final transferable = stopwatch.elapsedMilliseconds;
  print(
      'standard($standard ms)/transferable($transferable ms): ${standard / transferable}x');
  keepTimerRunning = false;
}

packageList(Uint8List data, bool useTransferable) {
  return useTransferable
      ? TransferableTypedData.fromList(<Uint8List>[data])
      : data;
}

class StartMessage {
  final SendPort sendPort;
  final bool useTransferable;

  StartMessage(this.sendPort, this.useTransferable);
}

runBatch({required bool useTransferable}) async {
  Timer.run(idleTimer);
  final port = ReceivePort();
  final inbox = StreamIterator<dynamic>(port);
  final worker = await Isolate.spawn(
      isolateMain, StartMessage(port.sendPort, useTransferable),
      paused: true);
  final workerCompleted = Completer<bool>();
  final workerExitedPort = ReceivePort()
    ..listen((_) => workerCompleted.complete(true));
  worker.addOnExitListener(workerExitedPort.sendPort);
  worker.resume(worker.pauseCapability!);

  await inbox.moveNext();
  final outbox = inbox.current;
  final workWatch = new Stopwatch();
  final data = new Uint8List(toIsolateSize);

  while (iteration-- > 0) {
    final packagedData = packageList(data, useTransferable);
    workWatch.start();
    outbox.send(packagedData);
    await inbox.moveNext();

    final received = inbox.current;
    final receivedData = received is TransferableTypedData
        ? received.materialize().asUint8List()
        : received;

    int time = workWatch.elapsedMilliseconds;
    print('${time}ms for round-trip');
    workWatch.reset();

    Expect.equals(data.length, receivedData.length);
  }
  outbox.send(null);

  await workerCompleted.future;
  workerExitedPort.close();
  port.close();
}

Future<Null> isolateMain(StartMessage startMessage) async {
  final port = new ReceivePort();
  final inbox = new StreamIterator<dynamic>(port);
  startMessage.sendPort.send(port.sendPort);
  final data = Uint8List.view(new Uint8List(fromIsolateSize).buffer);
  while (true) {
    await inbox.moveNext();
    final received = inbox.current;
    if (received == null) {
      break;
    }
    final receivedData =
        received is TransferableTypedData ? received.materialize() : received;

    final packagedData = packageList(data, startMessage.useTransferable);

    startMessage.sendPort.send(packagedData);
  }
  port.close();
}

final Stopwatch idleWatch = new Stopwatch();

void idleTimer() {
  idleWatch.stop();
  final time = idleWatch.elapsedMilliseconds;
  if (time > 5) print('${time}ms since last checkin');
  idleWatch.reset();
  idleWatch.start();
  if (keepTimerRunning) {
    Timer.run(idleTimer);
  }
}
