// 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 _ = require('lodash');
var debug = require('debug')('background:index');
var domready = require('domready');

var AuthHandler = require('./auth-handler');
var extensionErrors = require('../../../src/browser/extension-errors');
var getOrigin = require('./util').getOrigin;
var Nacl = require('./nacl');


domready(function() {
  // Start!
  var bp = new BackgroundPage();
  chrome.runtime.onConnect.addListener(
    bp.handleNewContentScriptConnection.bind(bp));

  // Set bp on the window so it will be accessable from options page.
  window.bp = bp;
  // Expose the state object so options page and background can share it and
  // stay in sync.
  bp.state = require('../state');
});

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

  // Map that stores instanceId -> port so messages can be routed back to the
  // port they came from.
  this.ports = {};

  // Map that stores port -> instanceId list so browspr can cleanup the
  // instances corresponding when the port when the port closes.
  this.instanceIds = new Map();

  debug('background script loaded');
}

// Start listening to messages from the Nacl plugin.
BackgroundPage.prototype.registerNaclListeners = function() {
  this.nacl.on('message', this.handleMessageFromNacl.bind(this));
  this.nacl.on('crash', this.handleNaclCrash.bind(this));
};

// Handle messages coming from Nacl by send them to the associated port.
BackgroundPage.prototype.handleMessageFromNacl = function(msg) {
  var instanceId = msg.instanceId;
  var port = this.ports[instanceId];
  if (!port) {
    console.error('Message received not matching instance id: ', instanceId);
    return;
  }
  port.postMessage(msg);
};


// Handle messages coming from a content script.
BackgroundPage.prototype.handleMessageFromContentScript = function(port, msg) {
  var bp = this;

  if (!this.naclPluginIsActive()) {
    // Start the plugin if it is not started.
    this.startNaclPlugin(handleMessage.bind(bp, port, msg));
  } else {
    handleMessage(port, msg);
  }

  function handleMessage(port, msg) {
    // Wrap in process.nextTick so chrome stack traces can use sourceMap.
    process.nextTick(function() {
      debug('background received message from content script.', msg);

      // Dispatch on the type of the message.
      switch (msg.type) {
        // From vanadium app.
        case 'browsprMsg':
          return bp.handleBrowsprMessage(port, msg);
        case 'browsprCleanup':
          return bp.handleBrowsprCleanup(port, msg);
        case 'createInstance':
          return bp.handleCreateInstance(port, msg);
        case 'auth':
          return bp.authHandler.handleAuthMessage(port);

        // From bless.
        case 'assocAccount:finish':
          return bp.authHandler.handleFinishAuth(port, msg);

        // ONLY for tests.
        case 'intentionallyPanic':
          return bp._triggerIntentionalPanic();

        default:
          console.error('unknown message.', msg);
      }
    });
  }
};

// Trigger a panic in the plug-in (only for tests).
BackgroundPage.prototype._triggerIntentionalPanic = function() {
  if (process.env.ALLOW_INTENTIONAL_CRASH) {
    var panicMsg = {
      type: 'intentionallyPanic',
      instanceId: 0,
      origin: '',
      body: ''
    };
    this.nacl.sendMessage(panicMsg);
  }
};

// Handle a content script connecting to this background script.
BackgroundPage.prototype.handleNewContentScriptConnection = function(port) {
  port.onMessage.addListener(
    this.handleMessageFromContentScript.bind(this, port));

  var bp = this;
  port.onDisconnect.addListener(function() {
    var instanceIds = bp.instanceIds.get(port) || [];
    instanceIds.forEach(function(instanceId) {
      bp.handleBrowsprCleanup(port, {body: {instanceId: instanceId}});
    });
  });
};

// Clean up an instance, and tell Nacl to clean it up as well.
BackgroundPage.prototype.handleBrowsprCleanup = function(port, msg) {
  function sendCleanupFinishedMessage() {
    safePostMessage(port, {type: 'browsprCleanupFinished'});
  }

  if (!this.naclPluginIsActive()) {
    // If the plugin isn't started, no need to clean it up.
    sendCleanupFinishedMessage();
    return;
  }

  var instanceId = msg.body.instanceId;

  if (!this.ports[instanceId]) {
    return console.error('Got cleanup message from instance ' + instanceId +
        ' with no associated port.');
  }

  if (this.ports[instanceId] !== port) {
    return console.error('Got cleanup message for instance ' + instanceId +
        ' that does not match port.');
  }

  var bp = this;
  var now = Date.now();
  this.nacl.cleanupInstance(instanceId, function() {
    var end = Date.now();
    console.log('Cleaned up instance: ' + instanceId + ' in ' +
                (end - now) + ' ms');
    bp.instanceIds.set(port, _.remove(bp.instanceIds.get(port), [instanceId]));
    if (bp.instanceIds.get(port).length === 0) {
      bp.instanceIds.delete(port);
    }
    delete bp.ports[instanceId];
    sendCleanupFinishedMessage();
    bp.stopNaclPluginIfUnused();
  });
};

BackgroundPage.prototype.isValidMessageForPort = function(msg, port) {
  var body = msg.body;
  if (!body) {
    console.error('Got message with no body: ', msg);
    return false;
  }
  if (!body.instanceId) {
    console.error('Got message with no instanceId: ', msg);
    return false;
  }
  if (this.ports[body.instanceId] && this.ports[body.instanceId] !== port) {
    console.error('Got browspr message with instanceId ' +
        body.instanceId + ' that does not match port.');
    return false;
  }
  return true;
};

BackgroundPage.prototype.assocPortAndInstanceId = function(port, instanceId) {
  // Store the instanceId->port.
  this.ports[instanceId] = port;
  // Store the port->instanceId.
  this.instanceIds.set(port,
      _.union(this.instanceIds.get(port) || [], [instanceId]));

  // Cache the origin on the port object.
  port.origin = port.origin || getOrigin(port.sender.url);
};


// Handle an createInstance message.
BackgroundPage.prototype.handleCreateInstance = function(port, msg) {
  if (!this.isValidMessageForPort(msg, port)) {
    return console.error('Invalid port for message.  Ignoring.');
  }

  var body = msg.body;
  this.assocPortAndInstanceId(port, body.instanceId);

  this.nacl.channel.performRpc('create-instance', {
    instanceId: body.instanceId,
    origin: port.origin,
    namespaceRoots: body.settings.namespaceRoots,
    proxy: body.settings.proxy
  }, function(err) {
    if (err) {
      return safePostMessage(port, {type: 'createInstance:error', error: err});
    }
    safePostMessage(port, {type: 'createInstance:success'});
  });
};

// Handle messages that will be sent to Nacl.
BackgroundPage.prototype.handleBrowsprMessage = function(port, msg) {
  if (!this.isValidMessageForPort(msg, port)) {
    return;
  }

  var body = msg.body;
  this.assocPortAndInstanceId(port, body.instanceId);

  var naclMsg = {
    type: msg.type,
    instanceId: parseInt(body.instanceId),
    origin: port.origin,
    body: body.msg
  };
  return this.nacl.sendMessage(naclMsg);
};

// Return true if the nacl plug-in is running.
BackgroundPage.prototype.naclPluginIsActive = function() {
  return this.hasOwnProperty('nacl') && this.nacl.isReady;
};

// Start the nacl plug-in -- add it to the page and register handlers.
BackgroundPage.prototype.startNaclPlugin = function(cb) {
  var bp = this;
  cb = cb || function() {};

  if (!bp.nacl) {
    bp.nacl = new Nacl();
    bp.registerNaclListeners();
    bp.nacl.once('ready', function() {
      bp.authHandler = new AuthHandler(bp.nacl.channel);
    });
  }

  bp.nacl.once('ready', cb.bind(bp));
};

// Stop the nacl plugin if it is not currently used.
BackgroundPage.prototype.stopNaclPluginIfUnused = function() {
  if (Object.keys(this.ports).length === 0) {
    this.stopNaclPlugin();
  }
};

// Stop the nacl plug-in - remove it from the page and clean up state.
BackgroundPage.prototype.stopNaclPlugin = function() {
  this.nacl.destroy();
  delete this.nacl;
};

// Stop and start the nacl plug-in
BackgroundPage.prototype.restartNaclPlugin = function(cb) {
  cb = cb || function() {};
  if (this.naclPluginIsActive()) {
    this.stopNaclPlugin();
  }
  this.startNaclPlugin(cb);
};

// Returns an array of all active port objects.
BackgroundPage.prototype.getAllPorts = function() {
  var ports = [];
  _.forEach(this.ports, function(portArray) {
    ports = ports.concat(portArray);
  });
  // Sort the ports array so that _.uniq can use a faster search algorithm.
  ports = _.sortBy(ports);
  // The second argument to _.uniq is whether the array is sorted.
  return _.uniq(ports, true);
};

// Restart nacl when it crashes.
BackgroundPage.prototype.handleNaclCrash = function(msg) {
  // Log the crash to the extension's console.
  console.error('NACL plugin crashed.');
  if (msg) {
    console.error(msg);
  }

  // Restart the plugin
  this.stopNaclPlugin();

  // Notify all content scripts about the failure.
  var crashNotificationMsg = {
    type: 'crash',
    body: new extensionErrors.ExtensionCrashError(msg)
  };
  this.getAllPorts().forEach(function(port) {
    safePostMessage(port, crashNotificationMsg);
  });
};

function safePostMessage(port, msg) {
  try {
    port.postMessage(msg);
  } catch (e) {
    // Port no longer exists.  Safe to ignore.
  }
}
