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

/// @assertion void removeErrorListener(
///                    SendPort port
///                 )
///    Stop listening for uncaught errors through port.
///    The port should be a port that is listening for errors through
/// addErrorListener. This call requests that the isolate stops sending errors
/// on the port.
///    If the same port has been passed via addErrorListener more than once,
/// only one call to removeErrorListener is needed to stop it from receiving
/// errors.
///    Closing the receive port at the end of the send port will not stop
/// the isolate from sending errors, they are just going to be lost.
///
/// @description Check that closing receive port does not affect the isolate and
/// other error listeners.
///
/// @author a.semenov@unipro.ru

import "dart:isolate";
import "dart:async";
import "../../../Utils/expect.dart";
import "IsolateUtil.dart";

test() async {
  ReceivePort errorPort1 = new ReceivePort();
  StreamIterator errors1 = new StreamIterator(errorPort1);
  ReceivePort errorPort2 = new ReceivePort();
  StreamIterator errors2 = new StreamIterator(errorPort2);

  ErrorServer server = await ErrorServer.spawn(
    onError:errorPort1.sendPort,
    errorsAreFatal:false
  );
  server.isolate.addErrorListener(errorPort2.sendPort);

  for (int i=0; i<3; i++) {
    server.generateError();
    Expect.isTrue(await errors1.moveNext());
    Expect.equals(i.toString(), errors1.current[0]);
    Expect.isTrue(await errors2.moveNext());
    Expect.equals(i.toString(), errors2.current[0]);
  }

  errorPort2.close();

  for (int i=3; i<5; i++) {
    server.generateError(); // these errors should not be received in errors2
    Expect.isTrue(await errors1.moveNext());
    Expect.equals(i.toString(), errors1.current[0]);
  }

  // check for unexpected events
  Expect.isFalse(await errors2.moveNext().timeout(ONE_SECOND, onTimeout:()=>false));

  server.requestStop();
  errorPort1.close();
  asyncEnd();
}

main() {
  asyncStart();
  test();
}
