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

// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit --no-enable-fast-object-copy
// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit --enable-fast-object-copy
// VMOptions=--no-enable-isolate-groups

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

void toplevel(port, message) {
  port.send("toplevel:$message");
}

Function createFuncToplevel() => (p, m) {
      p.send(m);
    };

class C {
  Function initializer;
  Function body;
  C()
      : initializer = ((p, m) {
          throw "initializer";
        }),
        body = ((p, m) {
          throw "body";
        }) {}
  static void staticFunc(port, message) {
    port.send("static:$message");
  }

  static Function createFuncStatic() => (p, m) {
        throw "static expr";
      };
  void instanceMethod(p, m) {
    throw "instanceMethod";
  }

  Function createFuncMember() => (p, m) {
        throw "instance expr";
      };
  void call(n, p) {
    throw "C";
  }
}

class Callable {
  void call(p, m) {
    p.send(["callable", m]);
  }
}

void main() {
  asyncStart();

  // Sendables are top-level functions and static functions only.
  testSendable("toplevel", toplevel);
  testSendable("static", C.staticFunc);
  // Unsendables are any closure - instance methods or function expression.
  var c = new C();
  testUnsendable("instance method", c.instanceMethod);
  testUnsendable("static context expression", createFuncToplevel());
  testUnsendable("static context expression", C.createFuncStatic());
  testUnsendable("initializer context expression", c.initializer);
  testUnsendable("constructor context expression", c.body);
  testUnsendable("instance method context expression", c.createFuncMember());

  // The result of `toplevel.call` and `staticFunc.call` may or may not be
  // identical to `toplevel` and `staticFunc` respectively. If they are not
  // equal, they may or may not be considered toplevel/static functions anyway,
  // and therefore sendable. The VM and dart2js currently disagree on whether
  // `toplevel` and `toplevel.call` are identical, both allow them to be sent.
  // If this is ever specified to something else, use:
  //     testUnsendable("toplevel.call", toplevel.call);
  //     testUnsendable("static.call", C.staticFunc.call);
  // instead.
  // These two tests should be considered canaries for accidental behavior
  // change rather than requirements.
  testSendable("toplevel", toplevel.call);
  testSendable("static", C.staticFunc.call);

  // Callable objects are sendable if general objects are (VM yes, dart2js no).
  // It's unspecified whether arbitrary objects can be sent. If it is specified,
  // add a test that `new Callable()` is either sendable or unsendable.

  // The call method of a callable object is a closure holding the object,
  // not a top-level or static function, so it should be blocked, just as
  // a normal method.
  testUnsendable("callable object", new Callable().call);

  asyncEnd();
  return;
}

// Create a receive port that expects exactly one message.
// Pass the message to `callback` and return the sendPort.
SendPort singleMessagePort(callback) {
  var p;
  p = new RawReceivePort((v) {
    p.close();
    callback(v);
  });
  return p.sendPort;
}

// A singleMessagePort that expects the message to be a specific value.
SendPort expectMessagePort(message) {
  asyncStart();
  return singleMessagePort((v) {
    Expect.equals(message, v);
    asyncEnd();
  });
}

void testSendable(name, func) {
  // Function as spawn message.
  Isolate.spawn(callFunc, [func, expectMessagePort("$name:spawn"), "spawn"]);

  // Send function to same isolate.
  var reply = expectMessagePort("$name:direct");
  singleMessagePort(callFunc).send([func, reply, "direct"]);

  // Send function to other isolate, call it there.
  reply = expectMessagePort("$name:other isolate");
  callPort().then((p) {
    p.send([func, reply, "other isolate"]);
  });

  // Round-trip function trough other isolate.
  echoPort((roundtripFunc) {
    Expect.identical(func, roundtripFunc, "$name:send through isolate");
  }).then((port) {
    port.send(func);
  });
}

// Creates a new isolate and a pair of ports that expect a single message
// to be sent to the other isolate and back to the callback function.
Future<SendPort> echoPort(callback(value)) {
  final completer = new Completer<SendPort>();
  SendPort replyPort = singleMessagePort(callback);
  late RawReceivePort initPort;
  initPort = new RawReceivePort((p) {
    completer.complete(p);
    initPort.close();
  });
  return Isolate.spawn(_echo, [replyPort, initPort.sendPort])
      .then((isolate) => completer.future);
}

void _echo(msg) {
  var replyPort = msg[0];
  late RawReceivePort requestPort;
  requestPort = new RawReceivePort((msg) {
    replyPort.send(msg);
    requestPort.close(); // Single echo only.
  });
  msg[1].send(requestPort.sendPort);
}

// Creates other isolate that waits for a single message, `msg`, on the returned
// port, and executes it as `msg[0](msg[1],msg[2])` in the other isolate.
Future<SendPort> callPort() {
  final completer = new Completer<SendPort>();
  SendPort initPort = singleMessagePort(completer.complete);
  return Isolate.spawn(_call, initPort).then((_) => completer.future);
}

void _call(initPort) {
  initPort.send(singleMessagePort(callFunc));
}

void testUnsendable(name, func) {
  asyncStart();
  Isolate.spawn(nop, func).then<void>((v) => throw "allowed spawn direct?",
      onError: (e, s) {
    asyncEnd();
  });
  asyncStart();
  Isolate.spawn(nop, [func]).then<void>((v) => throw "allowed spawn wrapped?",
      onError: (e, s) {
    asyncEnd();
  });

  asyncStart();
  var noReply = new RawReceivePort((_) {
    throw "Unexpected message: $_";
  });
  Expect.throws(() {
    noReply.sendPort.send(func);
  }, (_) => true, "send direct");
  Expect.throws(() {
    noReply.sendPort.send([func]);
  }, (_) => true, "send wrapped");
  scheduleMicrotask(() {
    noReply.close();
    asyncEnd();
  });

  // Try sending through other isolate.
  asyncStart();
  echoPort((v) {
    Expect.equals(0, v);
  }).then((p) {
    try {
      p.send(func);
    } finally {
      p.send(0); //   Closes echo port.
    }
  }).then<void>((p) => throw "unreachable 2", onError: (e, s) {
    asyncEnd();
  });
}

void nop(_) {}

void callFunc(message) {
  message[0](message[1], message[2]);
}
