// 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.

/**
 * @fileoverview Handles auth requests to Nacl.
 */

var _ = require('lodash');

var getOrigin = require('./util').getOrigin;
var random = require('../../../src/lib/random');

module.exports = AuthHandler;

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

  this._channel = channel;

  // Map for tabIds to ports.
  this._ports = {};
}

// Get an access token from the chrome.identity API.
// See https://developer.chrome.com/apps/app_identity
AuthHandler.prototype.getAccessToken = function(cb) {
  if (process.env.TEST_ACCESS_TOKEN) {
    return process.nextTick(cb.bind(null, null, process.env.TEST_ACCESS_TOKEN));
  }

  // This will return an access token for the profile that the user is
  // signed in to chrome as.  If the user is not signed in to chrome, an
  // OAuth window will pop up and ask them to sign in.
  //
  // For now, we don't have a way to ask the user which profile they would
  // like to use.  However, once the `chrome.identity.getAccounts` API call
  // gets out of dev/beta channel, we can get a list of accounts and prompt
  // the user for which one they would like to use with vanadium.
  chrome.identity.getAuthToken({
    interactive: true
  }, function(token) {
    // Wrap in process.nextTick so chrome stack traces can use sourceMap.
    process.nextTick(function(){
      if (chrome.runtime.lastError) {
        console.error('Error getting auth token.', chrome.runtime.lastError);
        return cb(chrome.runtime.lastError);
      }

      return cb(null, token);
    });
  });
};

// Get the name of all accounts from wspr.  Will be empty if no root account
// exists.
AuthHandler.prototype.getAccounts = function(cb) {
  this._channel.performRpc('auth:get-accounts', {}, cb);
};

// Get an access token from the user and use it to create the root account on
// wspr.
AuthHandler.prototype.createAccount = function(cb) {
  var ah = this;
  this.getAccessToken(function(err, token) {
    if (err) {
      return cb(err);
    }

    // If getAccessToken returns an empty token we shouldn't send it to the
    // identity server. Instead we directly pass an error to the callback which
    // will purge the cache and try again.
    if (!token) {
      return cb(new Error('getAccessToken returned an empty token.'), null,
        token);
    }

    ah._channel.performRpc('auth:create-account', {token: token},
      function(err, createdAccount) {
        cb(err, createdAccount, token);
      });
  });
};

// Check if an origin is already associated with an account on wspr.
AuthHandler.prototype.originHasAccount = function(origin, cb) {
  this._channel.performRpc('auth:origin-has-account', {origin: origin}, cb);
};

// Associate the account with the origin on wspr.
AuthHandler.prototype.associateAccount =
  function(account, origin, caveats, cb) {
    this._channel.performRpc('auth:associate-account', {
      account: account,
      origin: origin,
      caveats: caveats
    }, cb);
};

// Pop up a new tab asking the user to chose their caveats.
AuthHandler.prototype.getCaveats = function(account, origin, port) {
  var tabId = port.sender.tab.id;

  // Check if the port exists and has started an auth flow within the past 5
  // seconds.
  if (this._ports[tabId]) {
    var p = this._ports[tabId];
    if (p.authTime && (Date.now() - p.authTime) < 5000) {
      // Authorization is already in progress. Do nothing.
      console.log('Authorization is already in progress for tab: ' + tabId);
      return;
    }
  }

  // Store the port by its tab id.
  this._ports[tabId] = port;

  // Store the account name, random salt, and timestamp on the port.
  port.account = account;
  port.authState = random.hex();
  port.authTime = Date.now();

  // Get  currently active tab in the window.
  var windowId = port.sender.tab.windowId;
  chrome.tabs.query({active: true, windowId: windowId}, function(tabs) {
    // Store the current tab id so we can switch back to it after the addcaveats
    // tab is removed.  Note that the currently active tab might not be the same
    // as the tab that is requesting authentication.
    if (tabs && tabs[0] && tabs[0].id) {
      port.currentTabId = tabs[0].id;
    }

    chrome.tabs.create({
      url: chrome.extension.getURL('html/addcaveats.html') + '?webappId=' +
        port.sender.tab.id + '&origin=' + encodeURIComponent(origin) +
        '&authState=' + port.authState
    });
  });
};

// Handle incoming 'auth' message.
AuthHandler.prototype.handleAuthMessage = function(port) {
  port.postMessage({
    type: 'auth:received'
  });

  var origin;
  try {
    origin = getOrigin(port.sender.url);
  } catch (err) {
    return sendErrorToContentScript('auth', port, err);
  }

  var ah = this;

  this.getAccounts(function(err, accounts) {
    if (err) {
      return sendErrorToContentScript('auth', port, err);
    }

    if (!accounts || accounts.length === 0) {
      // No account exists.  Create one and then call getCaveats.
      var retry = true;
      var createAccountCallback = function(err, createdAccount, token) {
        if (err) {
          // If the token we received from chrome.identity.getAuthToken failed
          // to authenticate for the identity server, it may because that the
          // cached token has expired.
          // So, we remove the token from the cache and retry once.
          // TODO(suharshs,nlacasse): Filter by a more specific set of errors.
          if (retry && token) {
            retry = false;
            return chrome.identity.removeCachedAuthToken({
              'token': token
            }, function(){
              ah.createAccount(createAccountCallback);
            });
          } else if (retry) {
            // If the token was not returned from getAuthToken, force the logout
            // of the user and try again.
            // This usually happens when a user has changed their password from
            // a different browser instance and the current browser isn't logged
            // into their new account.
            return chrome.identity.launchWebAuthFlow({
              'url': 'https://accounts.google.com/logout'
            }, function(tokenUrl) {
              ah.createdAccount(createAccountCallback);
            });
          }
          return sendErrorToContentScript('auth', port, err);
        }
        ah.getCaveats(createdAccount, origin, port);
      };

      ah.createAccount(createAccountCallback);
    } else {
      // At least one account already exists. Use the first one.
      var account = accounts[0];

      // Check if origin is associated.
      ah.originHasAccount(origin, function(err, hasAccount) {
        if (err) {
          return sendErrorToContentScript('auth', port, err);
        }

        if (hasAccount) {
          // Origin already associated.  Return success.
          port.postMessage({
            type: 'auth:success',
            account: account
          });
        } else {
          // No origin associated.  Get caveats and then associate.
          ah.getCaveats(account, origin, port);
        }
      });
    }
  });
};

AuthHandler.prototype.handleFinishAuth = function(caveatsPort, msg) {
  if (caveatsPort.sender.url.indexOf(chrome.extension.getURL(
      'html/addcaveats.html')) !== 0) {
    console.error('invalid requester for associateAccount:finish');
    return;
  }

  // Remove the caveats tab.
  chrome.tabs.remove(caveatsPort.sender.tab.id);

  var webappPort = this._ports[msg.webappId];
  delete this._ports[msg.webappId];

  if (!webappPort) {
    return console.error('No webapp port found.');
  }

  // Switch back to the last active tab.
  if (webappPort.currentTabId) {
    chrome.tabs.update(webappPort.currentTabId, {active: true});
  }

  if (msg.cancel) {
    return sendErrorToContentScript('auth', webappPort,
        new Error('User declined to bless origin.'));
  }

  if (msg.origin !== getOrigin(webappPort.sender.url)) {
    return sendErrorToContentScript('auth', webappPort,
        new Error('Invalid origin.'));
  }

  if (msg.authState !== webappPort.authState) {
    return sendErrorToContentScript('auth', webappPort,
        new Error('Port not authorized.'));
  }

  if (!webappPort.account) {
    return sendErrorToContentScript('auth', webappPort,
        new Error('No port.account.'));
  }

  if (!msg.caveats || msg.caveats.length === 0) {
    return sendErrorToContentScript('auth', webappPort,
        new Error('No caveats selected'));
  }

  this.associateAccount(webappPort.account, msg.origin, msg.caveats,
    function(err) {
      if (err) {
        return sendErrorToContentScript('auth', webappPort, err);
      }
      webappPort.postMessage({
        type: 'auth:success',
        account: webappPort.account
      });
    });
};

AuthHandler.prototype.getAllPorts = function() {
  return _.values(this._ports);
};

// Convert an Error object into a bare Object with the same properties.  We do
// this because port.postMessage calls JSON.stringify, which ignores the message
// and stack properties on Error objects.
function errorToObject(err) {
  var obj = {};
  Object.getOwnPropertyNames(err).forEach(function(key) {
    obj[key] = err[key];
  });
  return obj;
}

// Helper functions to send error message back to calling content script.
function sendErrorToContentScript(type, port, err) {
  console.error(err);
  port.postMessage({
    type: type + ':error',
    error: errorToObject(err)
  });
}
