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

import "dart:isolate";
import "dart:async";
import "package:expect/async_helper.dart";
import "package:expect/expect.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();

  // top-level functions, static functions, closures, instance methods
  // or function expressions are not sendable to an isolate spawned using
  // spawnUri.
  testUnsendable("toplevel", toplevel);
  testUnsendable("static", C.staticFunc);
  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());
  testUnsendable("toplevel", toplevel.call);
  testUnsendable("static", C.staticFunc.call);
  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();
  });
}

// 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)) {
  Completer<SendPort> 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() {
  Completer<SendPort> 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.spawnUri(Uri.parse("function_send_test.dart"), [], func).then<void>(
    (v) => throw "allowed spawn direct?",
    onError: (e, s) {
      asyncEnd();
    },
  );
  asyncStart();
  Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], [func]).then<void>(
    (v) => throw "allowed spawn wrapped?",
    onError: (e, s) {
      asyncEnd();
    },
  );
}

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