// 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.
/**
 * @unrestricted
 */
export default class ServiceManager {
  /**
   * @param {string} serviceName
   * @return {!Promise<?Service>}
   */
  createRemoteService(serviceName) {
    if (!this._remoteConnection) {
      const url = Root.Runtime.queryParam('service-backend');
      if (!url) {
        console.error('No endpoint address specified');
        return /** @type {!Promise<?Service>} */ (Promise.resolve(null));
      }
      this._remoteConnection = new Connection(new RemoteServicePort(url));
    }
    return this._remoteConnection._createService(serviceName);
  }

  /**
   * @param {string} appName
   * @param {string} serviceName
   * @return {!Promise<?Service>}
   */
  createAppService(appName, serviceName) {
    let url = appName + '.js';
    const remoteBase = Root.Runtime.queryParam('remoteBase');
    const debugFrontend = Root.Runtime.queryParam('debugFrontend');
    const isUnderTest = Host.isUnderTest();

    const queryParams = [];
    if (remoteBase) {
      queryParams.push('remoteBase=' + remoteBase);
    }
    if (debugFrontend) {
      queryParams.push('debugFrontend=' + debugFrontend);
    }
    if (isUnderTest) {
      queryParams.push('isUnderTest=true');
    }

    if (queryParams.length) {
      url += `?${queryParams.join('&')}`;
    }

    const worker = new Worker(url);
    const connection = new Connection(new WorkerServicePort(worker));
    return connection._createService(serviceName);
  }
}

/**
 * @unrestricted
 */
class Connection {
  /**
   * @param {!ServicePort} port
   */
  constructor(port) {
    this._port = port;
    this._port.setHandlers(this._onMessage.bind(this), this._connectionClosed.bind(this));

    this._lastId = 1;
    /** @type {!Map<number, function(?Object)>}*/
    this._callbacks = new Map();
    /** @type {!Map<string, !Service>}*/
    this._services = new Map();
  }

  /**
   * @param {string} serviceName
   * @return {!Promise<?Service>}
   */
  _createService(serviceName) {
    return this._sendCommand(serviceName + '.create').then(result => {
      if (!result) {
        console.error('Could not initialize service: ' + serviceName);
        return null;
      }
      const service = new Service(this, serviceName, result.id);
      this._services.set(serviceName + ':' + result.id, service);
      return service;
    });
  }

  /**
   * @param {!Service} service
   */
  _serviceDisposed(service) {
    this._services.delete(service._serviceName + ':' + service._objectId);
    if (!this._services.size) {
      // Terminate the connection since it is no longer used.
      this._port.close();
    }
  }

  /**
   * @param {string} method
   * @param {!Object=} params
   * @return {!Promise<?Object>}
   */
  _sendCommand(method, params) {
    const id = this._lastId++;
    const message = JSON.stringify({id: id, method: method, params: params || {}});
    return this._port.send(message).then(success => {
      if (!success) {
        return Promise.resolve(null);
      }
      return new Promise(fulfill => this._callbacks.set(id, fulfill));
    });
  }

  /**
   * @param {string} data
   */
  _onMessage(data) {
    let object;
    try {
      object = JSON.parse(data);
    } catch (e) {
      console.error(e);
      return;
    }
    if (object.id) {
      if (object.error) {
        console.error('Service error: ' + object.error);
      }
      this._callbacks.get(object.id)(object.error ? null : object.result);
      this._callbacks.delete(object.id);
      return;
    }

    const tokens = object.method.split('.');
    const serviceName = tokens[0];
    const methodName = tokens[1];
    const service = this._services.get(serviceName + ':' + object.params.id);
    if (!service) {
      console.error('Unable to lookup stub for ' + serviceName + ':' + object.params.id);
      return;
    }
    service._dispatchNotification(methodName, object.params);
  }

  _connectionClosed() {
    for (const callback of this._callbacks.values()) {
      callback(null);
    }
    this._callbacks.clear();
    for (const service of this._services.values()) {
      service._dispatchNotification('disposed');
    }
    this._services.clear();
  }
}

/**
 * @unrestricted
 */
export class Service {
  /**
   * @param {!Connection} connection
   * @param {string} serviceName
   * @param {string} objectId
   */
  constructor(connection, serviceName, objectId) {
    this._connection = connection;
    this._serviceName = serviceName;
    this._objectId = objectId;
    /** @type {!Map<string, function(!Object=)>}*/
    this._notificationHandlers = new Map();
  }

  /**
   * @return {!Promise}
   */
  dispose() {
    const params = {id: this._objectId};
    return this._connection._sendCommand(this._serviceName + '.dispose', params).then(() => {
      this._connection._serviceDisposed(this);
    });
  }

  /**
   * @param {string} methodName
   * @param {function(!Object=)} handler
   */
  on(methodName, handler) {
    this._notificationHandlers.set(methodName, handler);
  }

  /**
   * @param {string} methodName
   * @param {!Object=} params
   * @return {!Promise}
   */
  send(methodName, params) {
    params = params || {};
    params.id = this._objectId;
    return this._connection._sendCommand(this._serviceName + '.' + methodName, params);
  }

  /**
   * @param {string} methodName
   * @param {!Object=} params
   */
  _dispatchNotification(methodName, params) {
    const handler = this._notificationHandlers.get(methodName);
    if (!handler) {
      console.error('Could not report notification \'' + methodName + '\' on \'' + this._objectId + '\'');
      return;
    }
    handler(params);
  }
}

/**
 * @implements {ServicePort}
 * @unrestricted
 */
class RemoteServicePort {
  /**
   * @param {string} url
   */
  constructor(url) {
    this._url = url;
  }

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

  /**
   * @return {!Promise<boolean>}
   */
  _open() {
    if (!this._connectionPromise) {
      this._connectionPromise = new Promise(promiseBody.bind(this));
    }
    return this._connectionPromise;

    /**
     * @param {function(boolean)} fulfill
     * @this {RemoteServicePort}
     */
    function promiseBody(fulfill) {
      let socket;
      try {
        socket = new WebSocket(/** @type {string} */ (this._url));
        socket.onmessage = onMessage.bind(this);
        socket.onclose = onClose.bind(this);
        socket.onopen = onConnect.bind(this);
      } catch (e) {
        fulfill(false);
      }

      /**
       * @this {RemoteServicePort}
       */
      function onConnect() {
        this._socket = socket;
        fulfill(true);
      }

      /**
       * @param {!Event} event
       * @this {RemoteServicePort}
       */
      function onMessage(event) {
        this._messageHandler(event.data);
      }

      /**
       * @this {RemoteServicePort}
       */
      function onClose() {
        if (!this._socket) {
          fulfill(false);
        }
        this._socketClosed(!!this._socket);
      }
    }
  }

  /**
   * @override
   * @param {string} message
   * @return {!Promise<boolean>}
   */
  send(message) {
    return this._open().then(() => {
      if (this._socket) {
        this._socket.send(message);
        return true;
      }
      return false;
    });
  }

  /**
   * @override
   * @return {!Promise}
   */
  close() {
    return this._open().then(() => {
      if (this._socket) {
        this._socket.close();
        this._socketClosed(true);
      }
      return true;
    });
  }

  /**
   * @param {boolean=} notifyClient
   */
  _socketClosed(notifyClient) {
    this._socket = null;
    delete this._connectionPromise;
    if (notifyClient) {
      this._closeHandler();
    }
  }
}

/**
 * @implements {ServicePort}
 * @unrestricted
 */
class WorkerServicePort {
  /**
   * @param {!Worker} worker
   */
  constructor(worker) {
    this._worker = worker;

    let fulfill;
    this._workerPromise = new Promise(resolve => fulfill = resolve);

    this._worker.onmessage = onMessage.bind(this);
    this._worker.onclose = this._closeHandler;

    /**
     * @param {!Event} event
     * @this {WorkerServicePort}
     */
    function onMessage(event) {
      if (event.data === 'workerReady') {
        fulfill(true);
        return;
      }
      this._messageHandler(event.data);
    }
  }

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

  /**
   * @override
   * @param {string} message
   * @return {!Promise<boolean>}
   */
  send(message) {
    return this._workerPromise.then(() => {
      try {
        this._worker.postMessage(message);
        return true;
      } catch (e) {
        return false;
      }
    });
  }

  /**
   * @override
   * @return {!Promise}
   */
  close() {
    return this._workerPromise.then(() => {
      if (this._worker) {
        this._worker.terminate();
      }
      return false;
    });
  }
}

/* Legacy exported object */
self.Services = self.Services || {};

/* Legacy exported object */
Services = Services || {};

/** @constructor */
Services.ServiceManager = ServiceManager;

/** @constructor */
Services.ServiceManager.Service = Service;

Services.serviceManager = new ServiceManager();
