// 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 domready = require('domready');
var EE = require('events').EventEmitter;
var inherits = require('inherits');

var Channel = require('./channel');
var QueuedRpcChannelWrapper = require('./queued_channel');
var state = require('../state');

// Clean the extension blessing whenever the extension is updated.
// See https://developer.chrome.com/extensions/runtime#event-onInstalled
var cleanBlessingsOnStart = false;
chrome.runtime.onInstalled.addListener(function(details) {
  if (details.reason === 'update') {
    cleanBlessingsOnStart = true;
  }
});

module.exports = Nacl;

function Nacl() {
  if (!(this instanceof Nacl)) {
    return new Nacl();
  }

  EE.call(this);

  this._queuedMessages = [];

  // Wait until the dom is ready, then add 'load' and 'message' listeners on the
  // nacl plugin that will trigger events on this object.
  var nacl = this;
  domready(function(){
    nacl._naclElt = _createNaclElement();
    document.body.appendChild(nacl._naclElt);

    // 'load' listener must have useCapture argument set to 'true'.
    nacl._naclElt.addEventListener('load', nacl.emit.bind(nacl, 'load'), true);
    nacl._naclElt.addEventListener('crash', nacl.emit.bind(nacl, 'crash', null),
      true);
    nacl._naclElt.addEventListener('message', function(e) {
      var msg = e.data;
      if (msg instanceof ArrayBuffer) {
        // Message is response from a channel RPC.
        return nacl._directChannel.handleMessage(msg);
      }
      nacl.emit('message', msg);
    });

    // Channel for bi-directional RPCs.
    nacl._directChannel = new Channel(nacl._naclElt.postMessage.bind(nacl));
    nacl.channel = new QueuedRpcChannelWrapper(nacl._directChannel);

    // Send a signal to initialize the nacl plug-in.
    nacl._start();
  });
}

inherits(Nacl, EE);

// Create an embed tag that will contain the nacl plugin.
function _createNaclElement() {
  var naclElt = document.createElement('embed');

  var idAttr = document.createAttribute('id');
  idAttr.value = 'nacl';
  naclElt.setAttributeNode(idAttr);

  var srcAttr = document.createAttribute('src');
  srcAttr.value = '/nacl/main.nmf';
  naclElt.setAttributeNode(srcAttr);

  var typeAttr = document.createAttribute('type');
  typeAttr.value = 'application/x-nacl';
  naclElt.setAttributeNode(typeAttr);

  return naclElt;
}

// Send message from content script to Nacl.
Nacl.prototype.sendMessage = function(msg) {
  if (!this._initialized) {
    this._queuedMessages.push(msg);
    return;
  }
  this._naclElt.postMessage(msg);
};

Nacl.prototype._start = function() {
  var nacl = this;
  var settings = state.settings();
  console.log(settings);

  this.getBlessingRoot(settings.identitydBlessingUrl.value,
    function(err, identityBlessingRoot) {
      if (err) {
        return nacl.emit('crash', err.message);
      }

      var body = {
        cleanupBlessings: cleanBlessingsOnStart,
        identitydBlessingRoot: identityBlessingRoot,
        identityd: settings.identityd.value,
        namespaceRoot: settings.namespaceRoot.value,
        proxy: settings.proxy.value,
        logLevel: parseInt(settings.logLevel.value) || 0,
        logModule: settings.logModule.value || ''
      };

      cleanBlessingsOnStart = false;

      nacl._directChannel.performRpc('start', body, function(err) {
        if (err) {
          return nacl.emit('crash', err.message);
        }

        nacl._initialized = true;
        nacl._sendQueuedMessages();
        nacl.channel.ready();
        nacl.isReady = true;
        nacl.emit('ready');
      });
    });
};

Nacl.prototype._sendQueuedMessages = function() {
  var nacl = this;
  this._queuedMessages.forEach(function(msg) {
    nacl._naclElt.postMessage(msg);
  });
  this._queuedMessages = [];
  console.log('Sent queued messages');
};

// Cache blessind root so we don't fetch it every time we start NaCl.
var cachedBlessingRoot = null;
Nacl.prototype.getBlessingRoot = function(url, cb) {
  if (cachedBlessingRoot) {
    return process.nextTick(function() {
      cb(null, cachedBlessingRoot);
    });
  }

  console.log('Requesting blessing root from ' + url);
  var request = require('superagent');
  request
      .get(url)
      .accept('application/json')
      .end(function(err, res) {
        if (err) {
          cb(err);
        } else if (res.error) {
          cb(new Error('' + res.status + ': ' + res.message));
        } else {
          cachedBlessingRoot = res.body;
          cb(null, cachedBlessingRoot);
        }
      });
};

Nacl.prototype.cleanupInstance = function(instanceId, cb) {
  this.channel.performRpc('cleanup', {
    instanceId: instanceId
  }, cb);
};

// Destroy state associated with this Nacl instance.
// In particular, this removed the added embed tag.
Nacl.prototype.destroy = function() {
  this._naclElt.parentNode.removeChild(this._naclElt);
  this._naclElt = null;
};
