// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var EE = require('eventemitter2').EventEmitter2;
var inherits = require('inherits');

var types = require('./event-proxy-message-types');
var extnUtils = require('./extension-utils');
var errors = require('../verror/index');

var defaultTimeout = 5000; // ms

// ExtensionEventProxy sends messages to the extension, and listens for messages
// coming from the extension.
function ExtensionEventProxy(timeout){
  if (!(this instanceof ExtensionEventProxy)) {
    return new ExtensionEventProxy(timeout);
  }

  if (typeof timeout === 'undefined') {
    timeout = defaultTimeout;
  }

  EE.call(this);
  var proxy = this;
  this.onEvent = function(ev) {
    proxy.emit(ev.detail.type, ev.detail.body);
  };
  window.addEventListener(types.TO_PAGE, this.onEvent);

  this.waitingForExtension = true;

  // Queue of messages to send once we know the extension event proxy is
  // listening.
  this.queuedMessages = [];

  // Check to see if the extension is installed.
  extnUtils.isExtensionInstalled(function(err, isInstalled) {
    if (err) {
      proxy.emit('error', err);
    }

    // If not installed, emit ExtensionNotInstalledError.
    if (!isInstalled) {
      proxy.emit('error', new errors.ExtensionNotInstalledError());
      proxy._extensionNotInstalled = true;
      return;
    }

    // Otherwise, wait until the extension has loaded and is responding to
    // messages.
    proxy.waitForExtension(timeout);
  });

  // Echo any errors or crashes we receive to the console.
  this.on('error', function(err) {
    console.error('Error message received from content script:', err);
  });
  this.on('crash', function(err) {
    console.error('Crash message received from content script.');
    if (err) {
      console.error(err);
    }
  });
}

inherits(ExtensionEventProxy, EE);

ExtensionEventProxy.prototype.destroy = function() {
  this.removeAllListeners();
  window.removeEventListener(types.TO_PAGE, this.onEvent);
};

ExtensionEventProxy.prototype.send = function(type, body) {
  // If we are still waiting for the extension, queue messages to be sent later.
  if (this.waitingForExtension) {
    this.queuedMessages.push({
      type: type,
      body: body
    });
    return;
  }

  window.dispatchEvent(
    new window.CustomEvent(types.TO_EXTENSION, {
      detail: {
        type: type,
        body: body
      }
    })
  );
};

// Repeatedly ping the extension, and wait a specified time for it to respond.
// If we don't hear back, emit an error.
ExtensionEventProxy.prototype.waitForExtension = function(timeout) {
  this.waitInterval = setInterval(function() {
    window.dispatchEvent(new window.CustomEvent(types.EXTENSION_IS_READY));
  }, 200);

  var proxy = this;

  this.waitTimeout = setTimeout(function() {
    if (!proxy.waitingForExtension) {
      return;
    }
    proxy.waitingForExtension = false;

    clearInterval(proxy.waitInterval);

    var error = new Error('Timeout waiting for extension.');
    proxy.emit('error', error);
  }, timeout);

  // Once the extension is listening, clear the timeout and interval, and send
  // queued messages.
  window.addEventListener(types.EXTENSION_READY, function() {
    if (!proxy.waitingForExtension) {
      return;
    }
    proxy.waitingForExtension = false;
    clearInterval(proxy.waitInterval);
    clearTimeout(proxy.waitTimeout);

    proxy.queuedMessages.forEach(function(msg) {
      proxy.send(msg.type, msg.body);
    });
    proxy.queuedMessages = [];

    proxy.emit('connected');
  });
};

// Wrapper around 'send' method that will call callback with error and data when
// extension responds.
ExtensionEventProxy.prototype.sendRpc = function(type, data, cb) {
  if (this._extensionNotInstalled) {
    cb(new errors.ExtensionNotInstalledError());
    return;
  }

  function onSuccess(data) {
    removeListeners();
    cb(null, data);
  }

  // Handle rpc-specific errors.
  function onRpcError(data) {
    removeListeners();
    cb(objectToError(data.error));
  }

  // Handle errors and crashes, which can be triggered if the extension is not
  // running or if it crashes during initialization.
  function onError(err) {
    removeListeners();
    cb(objectToError(err));
  }

  var proxy = this;
  function removeListeners() {
    proxy.removeListener(type + ':success', onSuccess);
    proxy.removeListener(type + ':error', onRpcError);
    proxy.removeListener('crash', onError);
    proxy.removeListener('error', onError);
  }

  this.on(type + ':success', onSuccess);
  this.on(type + ':error', onRpcError);
  this.on('crash', onError);
  this.on('error', onError);

  // Send request.
  this.send(type, data);
};

// An error that gets sent via postMessage will be received as a plain Object.
// This function turns it back into an Error object.
function objectToError(obj) {
  if (obj instanceof Error) {
    return obj;
  }
  var err = new Error(obj.message);
  err.name = obj.name;
  err.stack = obj.stack;
  return err;
}

module.exports = new ExtensionEventProxy();
module.exports.ctor = ExtensionEventProxy;
