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

part of dart.isolate;

/**
 * The initial [IsolateStream] available by default for this isolate. This
 * [IsolateStream] is created automatically and it is commonly used to establish
 * the first communication between isolates (see [streamSpawnFunction] and
 * [streamSpawnUri]).
 */
final IsolateStream stream = new IsolateStream._fromOriginalReceivePort(port);

/**
 * A [MessageBox] creates an [IsolateStream], [stream], and an [IsolateSink],
 * [sink].
 *
 * Any message that is written into the [sink] (independent of the isolate) is
 * sent to the [stream] where its subscribers can react to the messages.
 */
class MessageBox {
  final IsolateStream stream;
  final IsolateSink sink;

  external MessageBox.oneShot();
  external MessageBox();
}

external bool _isCloseToken(var object);

/**
 * [IsolateStream]s, together with [IsolateSink]s, are the only means of
 * communication between isolates. Each IsolateStream has a corresponding
 * [IsolateSink]. Any message written into that sink will be delivered to
 * the stream and then dispatched to the stream's subscribers.
 */
class IsolateStream extends Stream<dynamic> {
  bool _isClosed = false;
  final ReceivePort _port;
  StreamController _controller = new StreamController(sync: true);

  IsolateStream._fromOriginalReceivePort(this._port) {
    _port.receive((message, replyTo) {
      assert(replyTo == null);
      _add(message);
    });
  }

  IsolateStream._fromOriginalReceivePortOneShot(this._port) {
    _port.receive((message, replyTo) {
      assert(replyTo == null);
      _add(message);
      close();
    });
  }

  void _add(var message) {
    if (_isCloseToken(message)) {
      close();
    } else {
      _controller.sink.add(message);
    }
  }

  /**
   * Close the stream from the receiving end.
   *
   * Closing an already closed port has no effect.
   */
  void close() {
    if (!_isClosed) {
      _isClosed = true;
      _port.close();
      _controller.close();
    }
  }

  StreamSubscription listen(void onData(event),
                            { void onError(error),
                              void onDone(),
                              bool cancelOnError}) {
      return _controller.stream.listen(onData,
                                       onError: onError,
                                       onDone: onDone,
                                       cancelOnError: cancelOnError);
  }
}

/**
 * [IsolateSink]s represent the feed for [IsolateStream]s. Any message written
 * to [this] is delivered to its respective [IsolateStream]. [IsolateSink]s are
 * created by [MessageBox]es.
 *
 * [IsolateSink]s can be transmitted to other isolates.
 */
abstract class IsolateSink extends EventSink<dynamic> {
  // TODO(floitsch): Actually it should be a StreamSink (being able to flow-
  // control).

  /**
   * Sends an asynchronous [message] to the linked [IsolateStream]. The message
   * is copied to the receiving isolate.
   *
   * The content of [message] can be: primitive values (null, num, bool, double,
   * String), instances of [IsolateSink]s, and lists and maps whose elements are
   * any of these. List and maps are also allowed to be cyclic.
   *
   * In the special circumstances when two isolates share the same code and are
   * running in the same process (e.g. isolates created via [spawnFunction]), it
   * is also possible to send object instances (which would be copied in the
   * process). This is currently only supported by the dartvm.  For now, the
   * dart2js compiler only supports the restricted messages described above.
   */
  void add(dynamic message);

  void addError(errorEvent);

  /** Closing multiple times is allowed. */
  void close();

  /**
   * Tests whether [other] is an [IsolateSink] feeding into the same
   * [IsolateStream] as this one.
   */
  bool operator==(var other);
}


/**
 * Creates and spawns an isolate that shares the same code as the current
 * isolate, but that starts from [topLevelFunction]. The [topLevelFunction]
 * argument must be a static top-level function or a static method that takes no
 * arguments.
 *
 * When any isolate starts (even the main script of the application), a default
 * [IsolateStream] is created for it. This sink is available from the top-level
 * getter [stream] defined in this library.
 *
 * [spawnFunction] returns an [IsolateSink] feeding into the child isolate's
 * default stream.
 *
 * The optional [unhandledExceptionCallback] argument is invoked whenever an
 * exception inside the isolate is unhandled. It can be seen as a big
 * `try/catch` around everything that is executed inside the isolate. The
 * callback should return `true` when it was able to handled the exception.
 */
external IsolateSink streamSpawnFunction(
    void topLevelFunction(),
    [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
