// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * @interface
 */
function Service() {
}

Service.prototype = {
  /**
   * @return {!Promise}
   */
  dispose() {},

  /**
   * @return {function(string)}
   */
  setNotify(notify) {}
};

/**
 * @unrestricted
 */
ServiceDispatcher = class {
  /**
   * @param {!ServicePort} port
   */
  constructor(port) {
    /** @type {!Map<string, !Object>} */
    this._objects = new Map();
    this._lastObjectId = 1;
    this._port = port;
    this._port.setHandlers(this._dispatchMessageWrapped.bind(this), this._connectionClosed.bind(this));
  }

  /**
   * @param {string} data
   */
  _dispatchMessageWrapped(data) {
    let message;
    try {
      message = JSON.parse(data);
      if (!(message instanceof Object)) {
        this._sendErrorResponse(message['id'], 'Malformed message');
        return;
      }
      this._dispatchMessage(message);
    } catch (e) {
      this._sendErrorResponse(message ? message['id'] : '', e.toString() + ' ' + e.stack);
    }
  }

  /**
   * @param {!Object} message
   */
  _dispatchMessage(message) {
    const domainAndMethod = message['method'].split('.');
    const serviceName = domainAndMethod[0];
    const method = domainAndMethod[1];

    if (method === 'create') {
      const extensions =
          self.runtime.extensions(Service).filter(extension => extension.descriptor()['name'] === serviceName);
      if (!extensions.length) {
        this._sendErrorResponse(message['id'], 'Could not resolve service \'' + serviceName + '\'');
        return;
      }
      extensions[0].instance().then(object => {
        const id = String(this._lastObjectId++);
        object.setNotify(this._notify.bind(this, id, serviceName));
        this._objects.set(id, object);
        this._sendResponse(message['id'], {id: id});
      });
    } else if (method === 'dispose') {
      const object = this._objects.get(message['params']['id']);
      if (!object) {
        console.error('Could not look up object with id for ' + JSON.stringify(message));
        return;
      }
      this._objects.delete(message['params']['id']);
      object.dispose().then(() => this._sendResponse(message['id'], {}));
    } else {
      if (!message['params']) {
        console.error('No params in the message: ' + JSON.stringify(message));
        return;
      }
      const object = this._objects.get(message['params']['id']);
      if (!object) {
        console.error('Could not look up object with id for ' + JSON.stringify(message));
        return;
      }
      const handler = object[method];
      if (!(handler instanceof Function)) {
        console.error('Handler for \'' + method + '\' is missing.');
        return;
      }
      object[method](message['params']).then(result => this._sendResponse(message['id'], result));
    }
  }

  _connectionClosed() {
    for (const object of this._objects.values()) {
      object.dispose();
    }
    this._objects.clear();
  }

  /**
   * @param {string} objectId
   * @param {string} serviceName
   * @param {string} method
   * @param {!Object} params
   */
  _notify(objectId, serviceName, method, params) {
    params['id'] = objectId;
    const message = {method: serviceName + '.' + method, params: params};
    this._port.send(JSON.stringify(message));
  }

  /**
   * @param {string} messageId
   * @param {!Object} result
   */
  _sendResponse(messageId, result) {
    const message = {id: messageId, result: result};
    this._port.send(JSON.stringify(message));
  }

  /**
   * @param {string} messageId
   * @param {string} error
   */
  _sendErrorResponse(messageId, error) {
    const message = {id: messageId, error: error};
    this._port.send(JSON.stringify(message));
  }
};

/**
 * @implements {ServicePort}
 * @unrestricted
 */
WorkerServicePort = class {
  /**
   * @param {!Port|!Worker} port
   */
  constructor(port) {
    this._port = port;
    this._port.onmessage = this._onMessage.bind(this);
    this._port.onerror = console.error;
  }

  /**
   * @override
   * @param {function(string)} messageHandler
   * @param {function(string)} closeHandler
   */
  setHandlers(messageHandler, closeHandler) {
    this._messageHandler = messageHandler;
    this._closeHandler = closeHandler;
  }

  /**
   * @override
   * @param {string} data
   * @return {!Promise}
   */
  send(data) {
    this._port.postMessage(data);
    return Promise.resolve();
  }

  /**
   * @override
   * @return {!Promise}
   */
  close() {
    return Promise.resolve();
  }

  /**
   * @param {!MessageEvent} event
   */
  _onMessage(event) {
    this._messageHandler(event.data);
  }
};

const dispatchers = [];

const worker = /** @type {!Object} */ (self);
const servicePort = new WorkerServicePort(/** @type {!Worker} */ (worker));
dispatchers.push(new ServiceDispatcher(servicePort));
