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

// 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;
bool keepTimerRunning;

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({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);
  }
}
