// 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 getOrigin = require('./util').getOrigin;

module.exports = AuthHandler;

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

  this._channel = channel;

  // Map from origins to the Vanadium app ports of tabs with active requests.
  // This keeps track of existing auth tabs for an origin so new ones are not
  // started.
  this._outstandingAuthRequests = {};

  // Map from caveat tab id to origin.
  this._caveatTabOrigins = {};

  // Handle tabs being closed.
  chrome.tabs.onRemoved.addListener(this.onRemovedTab.bind(this));
}

AuthHandler.prototype.onRemovedTab = function(tabId) {
  var origin = this._caveatTabOrigins[tabId];
  if (!origin) {
    return; // Not one of the caveat tabs.
  }

  delete this._caveatTabOrigins[tabId];

  if (origin in this._outstandingAuthRequests) {
    this.finishAuth({
      origin: origin,
      cancel: true,
    });
  }
};

// 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, appPort) {
  // Store the account name on the appPort.
  appPort.account = account;

  var outstandingAuthRequests = this._outstandingAuthRequests;
  var caveatTabOrigins = this._caveatTabOrigins;
  if (origin in this._outstandingAuthRequests) {
    outstandingAuthRequests[origin].push(appPort);

    // Switch to the corresponding open caveat tab.
    for (var tabId in caveatTabOrigins) {
      if (caveatTabOrigins[tabId] === origin) {
        var tabIdAsNumber = +tabId;
        chrome.tabs.update(tabIdAsNumber, {active: true});
        break;
      }
    }

    return;
  }
  outstandingAuthRequests[origin] = [appPort];

  // Get  currently active tab in the window.
  var windowId = appPort.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) {
      appPort.currentTabId = tabs[0].id;
    }

    chrome.tabs.create({
      url: chrome.extension.getURL('html/addcaveats.html') + '?origin=' +
        encodeURIComponent(origin)
    }, function(tab) {
      caveatTabOrigins[tab.id] = origin;
    });
  });
};

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

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

  var ah = this;

  this.getAccounts(function(err, accounts) {
    if (err) {
      return sendErrorToContentScript('auth', appPort, 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', appPort, err);
        }
        ah.getCaveats(createdAccount, origin, appPort);
      };

      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', appPort, err);
        }

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

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;
  }


  this.finishAuth(msg);

  // Close the caveats tab.
  // Note: This triggers a call onRemovedTab().
  chrome.tabs.remove(caveatsPort.sender.tab.id);
};

AuthHandler.prototype.finishAuth = function(msg) {
  var appPorts = this._outstandingAuthRequests[msg.origin];
  delete this._outstandingAuthRequests[msg.origin];
  if (!Array.isArray(appPorts)) {
    console.error('Finish auth flow request received for unknown origin');
    return;
  }

  var self = this;
  appPorts.forEach(function(appPort) {
    if (msg.origin !== getOrigin(appPort.sender.url)) {
      console.error('Invalid origin.');
      return;
    }

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

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

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

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

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

// 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)
  });
}
