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

/**
 * A multiplexing [RawReceivePort].
 *
 * Allows creating a number of [RawReceivePort] implementations that all send
 * messages through the same real `RawReceivePort`.
 *
 * This allows reducing the number of receive ports created, but adds an
 * overhead to each message.
 * If a library creates many short-lived receive ports, multiplexing might be
 * faster.
 *
 * To use multiplexing receive ports, create and store a
 * [RawReceivePortMultiplexer], and create receive ports by calling
 * `multiplexer.createRawReceivePort(handler)` where you would otherwise
 * write `new RawReceivePort(handler)`.
 *
 * Remember to [close] the multiplexer when it is no longer needed.
 * `
 * (TODO: Check if it really is faster - creating a receive port requires a
 * global mutex, so it may be a bottleneck, but it's not clear how slow it is).
 */
library pkg.isolate.multiplexreceiveport;

import "dart:isolate";
import "dart:collection";
import "lists.dart";

class _MultiplexRawReceivePort implements RawReceivePort {
  final RawReceivePortMultiplexer _multiplexer;
  final int _id;
  Function _handler;

  _MultiplexRawReceivePort(this._multiplexer, this._id, this._handler);

  void set handler(void handler(response)) {
    this._handler = handler;
  }

  void close() {
    _multiplexer._closePort(_id);
  }

  SendPort get sendPort => _multiplexer._createSendPort(_id);

  void _invokeHandler(message) { _handler(message); }
}

class _MultiplexSendPort implements SendPort {
  final SendPort _sendPort;
  final int _id;
  _MultiplexSendPort(this._id, this._sendPort);

  void send(message) {
    _sendPort.send(list2(_id, message));
  }
}

/**
 * A shared [RawReceivePort] that distributes messages to
 * [RawReceivePort] instances that it manages.
 */
class RawReceivePortMultiplexer {
  final RawReceivePort _port = new RawReceivePort();
  final Map<int, _MultiplexRawReceivePort> _map = new HashMap();
  int _nextId = 0;

  RawReceivePortMultiplexer() {
    _port.handler = _multiplexResponse;
  }

  RawReceivePort createRawReceivePort([void handler(value)]) {
    int id = _nextId++;
    var result = new _MultiplexRawReceivePort(this, id, handler);
    _map[id] = result;
    return result;
  }

  void close() {
    _port.close();
  }

  void _multiplexResponse(list) {
    int id = list[0];
    var message = list[1];
    _MultiplexRawReceivePort receivePort = _map[id];
    // If the receive port is closed, messages are dropped, just as for
    // the normal ReceivePort.
    if (receivePort == null) return;  // Port closed.
    receivePort._invokeHandler(message);
  }

  SendPort _createSendPort(int id) {
    return new _MultiplexSendPort(id, _port.sendPort);
  }

  void _closePort(int id) {
    _map.remove(id);
  }
}
