// Copyright (c) 2021, 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

import 'dart:async';

import 'package:expect/expect.dart';

import 'reload_utils.dart';

const N = 20;

main() async {
  if (!currentVmSupportsReload) return;

  await withTempDir((String tempDir) async {
    final dills = await generateDills(tempDir, dartTestFile(N));
    final reloader = await launchOn(dills[0] /*, verbose: true*/);

    await reloader.waitUntilStdoutContains('Initial child isolates launched');

    // Let's give the test some time to spawn isolates on the N parallel tracks.
    await Future.delayed(const Duration(milliseconds: 100));

    final reloadResult = await reloader.reload(dills[1]);
    Expect.equals('ReloadReport', reloadResult['type']);
    Expect.equals(true, reloadResult['success']);

    await reloader.waitUntilStdoutContains('All child isolates died normally');

    final int exitCode = await reloader.close();
    Expect.equals(0, exitCode);
  });
}

String dartTestFile(int N) => '''
import 'dart:async';
import 'dart:isolate';

import 'package:expect/expect.dart';

const int parallel = $N;

@pragma('vm:never-inline')
bool isDone() {
  return false; // @include-in-reload-0
  return true; // @include-in-reload-1
}

Future main() async {
  final done = ReceivePort();
  final results = ReceivePort();
  final errors = ReceivePort();
  for (int parallelTrack = 0; parallelTrack < parallel; ++parallelTrack) {
    const int sequenceNumber = 0;
    final fakeAttachOnExitHandler = ReceivePort();
    await Future.delayed(const Duration(milliseconds: 1));
    final childMessage = ChildMessage(
      parallelTrack,
      sequenceNumber,
      results.sendPort,
      done.sendPort,
      errors.sendPort,
      fakeAttachOnExitHandler.sendPort);
    await Isolate.spawn(
        child, childMessage,
        onExit: done.sendPort,
        onError: errors.sendPort,
        debugName: 'track-\$parallelTrack-\$sequenceNumber');
    fakeAttachOnExitHandler.first.then((dynamic message) {
      (message as SendPort).send(null);
    });
  }
  print('Initial child isolates launched');

  print('Waiting for reload to happen ...');
  while (!isDone()) {
    print(' -> Still waiting ...');
    await Future.delayed(const Duration(milliseconds: 50));
  }
  print('-> reload done');

  final allErrors = [];
  errors.listen((e) {
    print('error: \$e');
    allErrors.add(e);
  });

  print('Waiting for parallel track results ...');
  int childCount = 0;
  final lsi = StreamIterator(results);
  for (int i = 0; i < parallel; ++i) {
    Expect.isTrue(await lsi.moveNext());
    final result = lsi.current as ParallelTrackResult;
    print('Got result: \$result');
    childCount += result.sequenceNumber;
  }
  await lsi.cancel();
  print('-> total number of isolate started: \$childCount');
  print('Waiting for their onDone ...');

  final si = StreamIterator(done);
  for (int i = 0; i < childCount; ++i) {
    Expect.isTrue(await si.moveNext());
  }
  await si.cancel();
  print('All children died');

  errors.close();
  Expect.equals(0, allErrors.length);

  print('All child isolates died normally');
}

void child(ChildMessage message) async {
  // Wait for parent to die before spawning our child to ensure we
  // don't spawn isolates faster than they can die.
  final onParentExit = ReceivePort();
  message.attachParentOnExitListenerPort.send(onParentExit.sendPort);
  await onParentExit.first;

  if (!isDone()) {
    final attachOnExitListener = ReceivePort();
    final childMessage = message.next(attachOnExitListener.sendPort);
    Isolate.spawn(
        child, childMessage,
        onError: message.parallelTrackErrorPort,
        onExit: message.parallelTrackEndPort,
        debugName: 'track-\${message.parallelTrack}-\${message.sequenceNumber}');
    Isolate.current.addOnExitListener((await attachOnExitListener.first) as SendPort);
  } else {
    message.parallelTrackResultPort.send(message.result);
  }
}

class ChildMessage {
  final int parallelTrack;
  final int sequenceNumber;
  final SendPort parallelTrackResultPort;
  final SendPort parallelTrackEndPort;
  final SendPort parallelTrackErrorPort;
  final SendPort attachParentOnExitListenerPort;

  ChildMessage(this.parallelTrack,
               this.sequenceNumber,
               this.parallelTrackResultPort,
               this.parallelTrackEndPort,
               this.parallelTrackErrorPort,
               this.attachParentOnExitListenerPort);

  ChildMessage next(SendPort newAttachParentOnExitListenerPort) {
    return ChildMessage(parallelTrack,
               sequenceNumber + 1,
               parallelTrackResultPort,
               parallelTrackEndPort,
               parallelTrackErrorPort,
               newAttachParentOnExitListenerPort);
  }

  ParallelTrackResult get result {
    return ParallelTrackResult(parallelTrack, sequenceNumber + 1);
  }
}

class ParallelTrackResult {
  final int parallelTrack;
  final int sequenceNumber;
  ParallelTrackResult(this.parallelTrack, this.sequenceNumber);

  String toString() => 'ParallelTrackResult(\$parallelTrack, \$sequenceNumber)';
}
''';
