// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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

import "dart:isolate";
import "dart:async";
import "package:async_helper/async_helper.dart";

void isomain(SendPort replyPort) {
  RawReceivePort port = new RawReceivePort();
  port.handler = (v) {
    if (v == 0) {
      // Shut down when receiving the 0 message.
      port.close();
    } else {
      replyPort.send(v);
    }
  };
  replyPort.send(port.sendPort);
}

void main() {
  testExit();
  testCancelExit();
  testOverrideResponse();
}

void testExit() {
  bool mayComplete = false;
  asyncStart();
  var completer = new Completer(); // Completed by first reply from isolate.
  RawReceivePort reply = new RawReceivePort(completer.complete);
  late RawReceivePort onExitPort;
  onExitPort = new RawReceivePort((v) {
    if (v != "RESPONSE") throw "WRONG RESPONSE: $v";
    reply.close();
    onExitPort.close();
    if (!mayComplete) throw "COMPLETED EARLY";
    asyncEnd();
  });
  Isolate.spawn(isomain, reply.sendPort).then((Isolate isolate) {
    isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE");
    return completer.future;
  }).then((echoPort) {
    int counter = 4;
    reply.handler = (v) {
      if (v != counter) throw "WRONG REPLY";
      if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN";
      counter--;
      mayComplete = (counter == 0);
      echoPort.send(counter);
    };
    echoPort.send(counter);
  });
}

void testCancelExit() {
  bool mayComplete = false;
  asyncStart();
  var completer = new Completer(); // Completed by first reply from isolate.
  RawReceivePort reply = new RawReceivePort(completer.complete);
  RawReceivePort onExitPort2 = new RawReceivePort((_) {
    throw "RECEIVED EXIT MESSAGE";
  });
  late RawReceivePort onExitPort1;
  onExitPort1 = new RawReceivePort((_) {
    reply.close();
    onExitPort1.close();
    if (!mayComplete) throw "COMPLETED EARLY";
    new Timer(const Duration(milliseconds: 0), () {
      onExitPort2.close();
      asyncEnd();
    });
  });
  Isolate.spawn(isomain, reply.sendPort).then((Isolate isolate) {
    isolate.addOnExitListener(onExitPort2.sendPort);
    isolate.addOnExitListener(onExitPort1.sendPort);
    return completer.future.then((echoPort) {
      int counter = 4;
      reply.handler = (v) {
        if (v != counter) throw "WRONG REPLY";
        if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN";
        counter--;
        mayComplete = (counter == 0);
        if (counter == 1) {
          // Remove listener 2, keep listener 1.
          isolate.removeOnExitListener(onExitPort2.sendPort);
        }
        echoPort.send(counter);
      };
      echoPort.send(counter);
    });
  });
}

void testOverrideResponse() {
  bool mayComplete = false;
  asyncStart();
  var completer = new Completer(); // Completed by first reply from isolate.
  RawReceivePort reply = new RawReceivePort(completer.complete);
  late RawReceivePort onExitPort;
  onExitPort = new RawReceivePort((v) {
    if (v != "RESPONSE2") throw "WRONG RESPONSE: $v";
    reply.close();
    onExitPort.close();
    if (!mayComplete) throw "COMPLETED EARLY";
    asyncEnd();
  });
  Isolate.spawn(isomain, reply.sendPort).then((Isolate isolate) {
    isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE");
    isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE2");
    return completer.future;
  }).then((echoPort) {
    int counter = 4;
    reply.handler = (v) {
      if (v != counter) throw "WRONG REPLY";
      if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN";
      counter--;
      mayComplete = (counter == 0);
      echoPort.send(counter);
    };
    echoPort.send(counter);
  });
}
