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

// @dart = 2.9

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