// Copyright 2013 The Chromium 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 An UI component to host gaia auth extension in an iframe.
 * After the component binds with an iframe, call its {@code load} to start the
 * authentication flow. There are two events would be raised after this point:
 * a 'ready' event when the authentication UI is ready to use and a 'completed'
 * event when the authentication is completed successfully. If caller is
 * interested in the user credentials, he may supply a success callback with
 * {@code load} call. The callback will be invoked when the authentication is
 * completed successfully and with the available credential data.
 */

cr.define('cr.login', function() {
  'use strict';

  /**
   * Base URL of gaia auth extension.
   * @const
   */
  var AUTH_URL_BASE = 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik';

  /**
   * Auth URL to use for online flow.
   * @const
   */
  var AUTH_URL = AUTH_URL_BASE + '/main.html';

  /**
   * Auth URL to use for offline flow.
   * @const
   */
  var OFFLINE_AUTH_URL = AUTH_URL_BASE + '/offline.html';

  /**
   * Origin of the gaia sign in page.
   * @const
   */
  var GAIA_ORIGIN = 'https://accounts.google.com';

  /**
   * Supported params of auth extension. For a complete list, check out the
   * auth extension's main.js.
   * @type {!Array.<string>}
   * @const
   */
  var SUPPORTED_PARAMS = [
    'gaiaUrl',       // Gaia url to use;
    'gaiaPath',      // Gaia path to use without a leading slash;
    'hl',            // Language code for the user interface;
    'email',         // Pre-fill the email field in Gaia UI;
    'service',       // Name of Gaia service;
    'continueUrl',   // Continue url to use;
    'frameUrl',      // Initial frame URL to use. If empty defaults to gaiaUrl.
    'constrained'    // Whether the extension is loaded in a constrained window;
  ];

  /**
   * Supported localized strings. For a complete list, check out the auth
   * extension's offline.js
   * @type {!Array.<string>}
   * @const
   */
  var LOCALIZED_STRING_PARAMS = [
      'stringSignIn',
      'stringEmail',
      'stringPassword',
      'stringEmptyEmail',
      'stringEmptyPassword',
      'stringError'
  ];

  /**
   * Enum for the authorization mode, must match AuthMode defined in
   * chrome/browser/ui/webui/inline_login_ui.cc.
   * @enum {number}
   */
  var AuthMode = {
    DEFAULT: 0,
    OFFLINE: 1,
    DESKTOP: 2
  };

  /**
   * Enum for the auth flow.
   * @enum {number}
   */
  var AuthFlow = {
    GAIA: 0,
    SAML: 1
  };

  /**
   * Creates a new gaia auth extension host.
   * @param {HTMLIFrameElement|string} container The iframe element or its id
   *     to host the auth extension.
   * @constructor
   * @extends {cr.EventTarget}
   */
  function GaiaAuthHost(container) {
    this.frame_ = typeof container == 'string' ? $(container) : container;
    assert(this.frame_);
    window.addEventListener('message',
                            this.onMessage_.bind(this), false);
  }

  GaiaAuthHost.prototype = {
    __proto__: cr.EventTarget.prototype,

    /**
     * An url to use with {@code reload}.
     * @type {?string}
     * @private
     */
    reloadUrl_: null,

    /**
     * The domain name of the current auth page.
     * @type {string}
     */
    authDomain: '',

    /**
     * Invoked when authentication is completed successfully with credential
     * data. A credential data object looks like this:
     * <pre>
     * {@code
     * {
     *   email: 'xx@gmail.com',
     *   password: 'xxxx',  // May not present
     *   authCode: 'x/xx',  // May not present
     *   authMode: 'x',     // Authorization mode, default/offline/desktop.
     * }
     * }
     * </pre>
     * @type {function(Object)}
     * @private
     */
    successCallback_: null,

    /**
     * Invoked when the auth flow needs a user to confirm his/her passwords.
     * This could happen when there are more than one passwords scraped during
     * SAML flow. The embedder of GaiaAuthHost should show an UI to collect a
     * password from user then call GaiaAuthHost.verifyConfirmedPassword to
     * verify. If the password is good, the auth flow continues with success
     * path. Otherwise, confirmPasswordCallback_ is invoked again.
     * @type {function()}
     */
    confirmPasswordCallback_: null,

    /**
     * Similar to confirmPasswordCallback_ but is used when there is no
     * password scraped after a success authentication. The authenticated user
     * account is passed to the callback. The embedder should take over the
     * flow and decide what to do next.
     * @type {function(string)}
     */
    noPasswordCallback_: null,

    /**
     * Invoked when the authentication flow had to be aborted because content
     * served over an unencrypted connection was detected.
     */
    insecureContentBlockedCallback_: null,

    /**
     * Invoked to display an error message to the user when a GAIA error occurs
     * during authentication.
     * @type {function()}
     */
    missingGaiaInfoCallback_: null,

    /**
     * Invoked to record that the credentials passing API was used.
     * @type {function()}
     */
    samlApiUsedCallback_: null,

    /**
     * The iframe container.
     * @type {HTMLIFrameElement}
     */
    get frame() {
      return this.frame_;
    },

    /**
     * Sets confirmPasswordCallback_.
     * @type {function()}
     */
    set confirmPasswordCallback(callback) {
      this.confirmPasswordCallback_ = callback;
    },

    /**
     * Sets noPasswordCallback_.
     * @type {function()}
     */
    set noPasswordCallback(callback) {
      this.noPasswordCallback_ = callback;
    },

    /**
     * Sets insecureContentBlockedCallback_.
     * @type {function(string)}
     */
    set insecureContentBlockedCallback(callback) {
      this.insecureContentBlockedCallback_ = callback;
    },

    /**
     * Sets missingGaiaInfoCallback_.
     * @type {function()}
     */
    set missingGaiaInfoCallback(callback) {
      this.missingGaiaInfoCallback_ = callback;
    },

    /**
     * Sets samlApiUsedCallback_.
     * @type {function()}
     */
    set samlApiUsedCallback(callback) {
      this.samlApiUsedCallback_ = callback;
    },

    /**
     * Loads the auth extension.
     * @param {AuthMode} authMode Authorization mode.
     * @param {Object} data Parameters for the auth extension. See the auth
     *     extension's main.js for all supported params and their defaults.
     * @param {function(Object)} successCallback A function to be called when
     *     the authentication is completed successfully. The callback is
     *     invoked with a credential object.
     */
    load: function(authMode, data, successCallback) {
      var params = [];

      var populateParams = function(nameList, values) {
        if (!values)
          return;

        for (var i in nameList) {
          var name = nameList[i];
          if (values[name])
            params.push(name + '=' + encodeURIComponent(values[name]));
        }
      };

      populateParams(SUPPORTED_PARAMS, data);
      populateParams(LOCALIZED_STRING_PARAMS, data.localizedStrings);
      params.push('parentPage=' + encodeURIComponent(window.location.origin));
      params.push('needPassword=1');

      var url;
      switch (authMode) {
        case AuthMode.OFFLINE:
          url = OFFLINE_AUTH_URL;
          break;
        case AuthMode.DESKTOP:
          url = AUTH_URL;
          params.push('desktopMode=1');
          break;
        default:
          url = AUTH_URL;
      }
      url += '?' + params.join('&');

      this.frame_.src = url;
      this.reloadUrl_ = url;
      this.successCallback_ = successCallback;
      this.authFlow = AuthFlow.GAIA;
    },

    /**
     * Reloads the auth extension.
     */
    reload: function() {
      this.frame_.src = this.reloadUrl_;
      this.authFlow = AuthFlow.GAIA;
    },

    /**
     * Verifies the supplied password by sending it to the auth extension,
     * which will then check if it matches the scraped passwords.
     * @param {string} password The confirmed password that needs verification.
     */
    verifyConfirmedPassword: function(password) {
      var msg = {
        method: 'verifyConfirmedPassword',
        password: password
      };
      this.frame_.contentWindow.postMessage(msg, AUTH_URL_BASE);
    },

    /**
     * Invoked to process authentication success.
     * @param {Object} credentials Credential object to pass to success
     *     callback.
     * @private
     */
    onAuthSuccess_: function(credentials) {
      if (this.successCallback_)
        this.successCallback_(credentials);
      cr.dispatchSimpleEvent(this, 'completed');
    },

    /**
     * Checks if message comes from the loaded authentication extension.
     * @param {Object} e Payload of the received HTML5 message.
     * @type {boolean}
     */
    isAuthExtMessage_: function(e) {
      return this.frame_.src &&
          this.frame_.src.indexOf(e.origin) == 0 &&
          e.source == this.frame_.contentWindow;
    },

    /**
     * Event handler that is invoked when HTML5 message is received.
     * @param {object} e Payload of the received HTML5 message.
     */
    onMessage_: function(e) {
      var msg = e.data;

      if (!this.isAuthExtMessage_(e))
        return;

      if (msg.method == 'loginUILoaded') {
        cr.dispatchSimpleEvent(this, 'ready');
        return;
      }

      if (/^complete(Login|Authentication)$|^offlineLogin$/.test(msg.method)) {
        if (!msg.email && !this.email_ && !msg.skipForNow) {
          var msg = {method: 'redirectToSignin'};
          this.frame_.contentWindow.postMessage(msg, AUTH_URL_BASE);
          return;
        }
        this.onAuthSuccess_({email: msg.email,
                             password: msg.password,
                             gaiaId: msg.gaiaId,
                             useOffline: msg.method == 'offlineLogin',
                             usingSAML: msg.usingSAML || false,
                             chooseWhatToSync: msg.chooseWhatToSync,
                             skipForNow: msg.skipForNow || false,
                             sessionIndex: msg.sessionIndex || ''});
        return;
      }

      if (msg.method == 'confirmPassword') {
        if (this.confirmPasswordCallback_)
          this.confirmPasswordCallback_(msg.passwordCount);
        else
          console.error('GaiaAuthHost: Invalid confirmPasswordCallback_.');
        return;
      }

      if (msg.method == 'noPassword') {
        if (this.noPasswordCallback_)
          this.noPasswordCallback_(msg.email);
        else
          console.error('GaiaAuthHost: Invalid noPasswordCallback_.');
        return;
      }

      if (msg.method == 'authPageLoaded') {
        this.authDomain = msg.domain;
        this.authFlow = msg.isSAML ? AuthFlow.SAML : AuthFlow.GAIA;
        return;
      }

      if (msg.method == 'insecureContentBlocked') {
        if (this.insecureContentBlockedCallback_) {
          this.insecureContentBlockedCallback_(msg.url);
        } else {
          console.error(
              'GaiaAuthHost: Invalid insecureContentBlockedCallback_.');
        }
        return;
      }

      if (msg.method == 'switchToFullTab') {
        chrome.send('switchToFullTab', [msg.url]);
        return;
      }

      if (msg.method == 'missingGaiaInfo') {
        if (this.missingGaiaInfoCallback_) {
          this.missingGaiaInfoCallback_();
        } else {
          console.error('GaiaAuthHost: Invalid missingGaiaInfoCallback_.');
        }
        return;
      }

      if (msg.method == 'samlApiUsed') {
        if (this.samlApiUsedCallback_) {
          this.samlApiUsedCallback_();
        } else {
          console.error('GaiaAuthHost: Invalid samlApiUsedCallback_.');
        }
        return;
      }

      console.error('Unknown message method=' + msg.method);
    }
  };

  /**
   * The current auth flow of the hosted gaia_auth extension.
   * @type {AuthFlow}
   */
  cr.defineProperty(GaiaAuthHost, 'authFlow');

  GaiaAuthHost.SUPPORTED_PARAMS = SUPPORTED_PARAMS;
  GaiaAuthHost.LOCALIZED_STRING_PARAMS = LOCALIZED_STRING_PARAMS;
  GaiaAuthHost.AuthMode = AuthMode;
  GaiaAuthHost.AuthFlow = AuthFlow;

  return {
    GaiaAuthHost: GaiaAuthHost
  };
});
