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

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