// 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
 * Connect set-up state machine for Me2Me and IT2Me
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/**
 * @param {Element} pluginParent The node under which to add the client plugin.
 * @param {function(remoting.ClientSession):void} onOk Callback on success.
 * @param {function(remoting.Error):void} onError Callback on error.
 * @constructor
 */
remoting.SessionConnector = function(pluginParent, onOk, onError) {
  /**
   * @type {Element}
   * @private
   */
  this.pluginParent_ = pluginParent;

  /**
   * @type {function(remoting.ClientSession):void}
   * @private
   */
  this.onOk_ = onOk;

  /**
   * @type {function(remoting.Error):void}
   * @private
   */
  this.onError_ = onError;

  /**
   * @type {string}
   * @private
   */
  this.clientJid_ = '';

  /**
   * @type {remoting.ClientSession.Mode}
   * @private
   */
  this.connectionMode_ = remoting.ClientSession.Mode.ME2ME;

  // Initialize/declare per-connection state.
  this.reset();
};

/**
 * Reset the per-connection state so that the object can be re-used for a
 * second connection. Note the none of the shared WCS state is reset.
 */
remoting.SessionConnector.prototype.reset = function() {
  /**
   * Set to true to indicate that the user requested pairing when entering
   * their PIN for a Me2Me connection.
   *
   * @type {boolean}
   */
  this.pairingRequested = false;

  /**
   * String used to identify the host to which to connect. For IT2Me, this is
   * the first 7 digits of the access code; for Me2Me it is the host identifier.
   *
   * @type {string}
   * @private
   */
  this.hostId_ = '';

  /**
   * For paired connections, the client id of this device, issued by the host.
   *
   * @type {string}
   * @private
   */
  this.clientPairingId_ = '';

  /**
   * For paired connections, the paired secret for this device, issued by the
   * host.
   *
   * @type {string}
   * @private
   */
  this.clientPairedSecret_ = '';

  /**
   * String used to authenticate to the host on connection. For IT2Me, this is
   * the access code; for Me2Me it is the PIN.
   *
   * @type {string}
   * @private
   */
  this.passPhrase_ = '';

  /**
   * @type {string}
   * @private
   */
  this.hostJid_ = '';

  /**
   * @type {string}
   * @private
   */
  this.hostPublicKey_ = '';

  /**
   * @type {boolean}
   * @private
   */
  this.refreshHostJidIfOffline_ = false;

  /**
   * @type {remoting.ClientSession}
   * @private
   */
  this.clientSession_ = null;

  /**
   * @type {XMLHttpRequest}
   * @private
   */
  this.pendingXhr_ = null;

  /**
   * Function to interactively obtain the PIN from the user.
   * @type {function(boolean, function(string):void):void}
   * @private
   */
  this.fetchPin_ = function(onPinFetched) {};

  /**
   * @type {function(string, string, string,
   *                 function(string, string):void): void}
   * @private
   */
  this.fetchThirdPartyToken_ = function(
      tokenUrl, scope, onThirdPartyTokenFetched) {};

  /**
   * Host 'name', as displayed in the client tool-bar. For a Me2Me connection,
   * this is the name of the host; for an IT2Me connection, it is the email
   * address of the person sharing their computer.
   *
   * @type {string}
   * @private
   */
  this.hostDisplayName_ = '';
};

/**
 * Initiate a Me2Me connection.
 *
 * @param {remoting.Host} host The Me2Me host to which to connect.
 * @param {function(boolean, function(string):void):void} fetchPin Function to
 *     interactively obtain the PIN from the user.
 * @param {function(string, string, string,
 *                  function(string, string): void): void}
 *     fetchThirdPartyToken Function to obtain a token from a third party
 *     authenticaiton server.
 * @param {string} clientPairingId The client id issued by the host when
 *     this device was paired, if it is already paired.
 * @param {string} clientPairedSecret The shared secret issued by the host when
 *     this device was paired, if it is already paired.
 * @return {void} Nothing.
 */
remoting.SessionConnector.prototype.connectMe2Me =
    function(host, fetchPin, fetchThirdPartyToken,
             clientPairingId, clientPairedSecret) {
  this.connectMe2MeInternal_(
      host.hostId, host.jabberId, host.publicKey, host.hostName,
      fetchPin, fetchThirdPartyToken,
      clientPairingId, clientPairedSecret, true);
};

/**
 * Update the pairing info so that the reconnect function will work correctly.
 *
 * @param {string} clientId The paired client id.
 * @param {string} sharedSecret The shared secret.
 */
remoting.SessionConnector.prototype.updatePairingInfo =
    function(clientId, sharedSecret) {
  this.clientPairingId_ = clientId;
  this.clientPairedSecret_ = sharedSecret;
};

/**
 * Initiate a Me2Me connection.
 *
 * @param {string} hostId ID of the Me2Me host.
 * @param {string} hostJid XMPP JID of the host.
 * @param {string} hostPublicKey Public Key of the host.
 * @param {string} hostDisplayName Display name (friendly name) of the host.
 * @param {function(boolean, function(string):void):void} fetchPin Function to
 *     interactively obtain the PIN from the user.
 * @param {function(string, string, string,
 *                  function(string, string): void): void}
 *     fetchThirdPartyToken Function to obtain a token from a third party
 *     authenticaiton server.
 * @param {string} clientPairingId The client id issued by the host when
 *     this device was paired, if it is already paired.
 * @param {string} clientPairedSecret The shared secret issued by the host when
 *     this device was paired, if it is already paired.
 * @param {boolean} refreshHostJidIfOffline Whether to refresh the JID and retry
 *     the connection if the current JID is offline.
 * @return {void} Nothing.
 * @private
 */
remoting.SessionConnector.prototype.connectMe2MeInternal_ =
    function(hostId, hostJid, hostPublicKey, hostDisplayName,
             fetchPin, fetchThirdPartyToken,
             clientPairingId, clientPairedSecret,
             refreshHostJidIfOffline) {
  // Cancel any existing connect operation.
  this.cancel();

  this.hostId_ = hostId;
  this.hostJid_ = hostJid;
  this.hostPublicKey_ = hostPublicKey;
  this.fetchPin_ = fetchPin;
  this.fetchThirdPartyToken_ = fetchThirdPartyToken;
  this.hostDisplayName_ = hostDisplayName;
  this.connectionMode_ = remoting.ClientSession.Mode.ME2ME;
  this.refreshHostJidIfOffline_ = refreshHostJidIfOffline;
  this.updatePairingInfo(clientPairingId, clientPairedSecret);
  this.createSession_();
};

/**
 * Initiate an IT2Me connection.
 *
 * @param {string} accessCode The access code as entered by the user.
 * @return {void} Nothing.
 */
remoting.SessionConnector.prototype.connectIT2Me = function(accessCode) {
  var kSupportIdLen = 7;
  var kHostSecretLen = 5;
  var kAccessCodeLen = kSupportIdLen + kHostSecretLen;

  // Cancel any existing connect operation.
  this.cancel();

  var normalizedAccessCode = this.normalizeAccessCode_(accessCode);
  if (normalizedAccessCode.length != kAccessCodeLen) {
    this.onError_(remoting.Error.INVALID_ACCESS_CODE);
    return;
  }

  this.hostId_ = normalizedAccessCode.substring(0, kSupportIdLen);
  this.passPhrase_ = normalizedAccessCode;
  this.connectionMode_ = remoting.ClientSession.Mode.IT2ME;
  remoting.identity.callWithToken(this.connectIT2MeWithToken_.bind(this),
                                  this.onError_);
};

/**
 * Reconnect a closed connection.
 *
 * @return {void} Nothing.
 */
remoting.SessionConnector.prototype.reconnect = function() {
  if (this.connectionMode_ == remoting.ClientSession.Mode.IT2ME) {
    console.error('reconnect not supported for IT2Me.');
    return;
  }
  this.connectMe2MeInternal_(
      this.hostId_, this.hostJid_, this.hostPublicKey_, this.hostDisplayName_,
      this.fetchPin_, this.fetchThirdPartyToken_,
      this.clientPairingId_, this.clientPairedSecret_, true);
};

/**
 * Cancel a connection-in-progress.
 */
remoting.SessionConnector.prototype.cancel = function() {
  if (this.clientSession_) {
    this.clientSession_.removePlugin();
    this.clientSession_ = null;
  }
  if (this.pendingXhr_) {
    this.pendingXhr_.abort();
    this.pendingXhr_ = null;
  }
  this.reset();
};

/**
 * Get the connection mode (Me2Me or IT2Me)
 *
 * @return {remoting.ClientSession.Mode}
 */
remoting.SessionConnector.prototype.getConnectionMode = function() {
  return this.connectionMode_;
};

/**
 * Get host ID.
 *
 * @return {string}
 */
remoting.SessionConnector.prototype.getHostId = function() {
  return this.hostId_;
};

/**
 * Get host display name.
 *
 * @return {string}
 */
remoting.SessionConnector.prototype.getHostDisplayName = function() {
  return this.hostDisplayName_;
};

/**
 * Continue an IT2Me connection once an access token has been obtained.
 *
 * @param {string} token An OAuth2 access token.
 * @return {void} Nothing.
 * @private
 */
remoting.SessionConnector.prototype.connectIT2MeWithToken_ = function(token) {
  // Resolve the host id to get the host JID.
  this.pendingXhr_ = remoting.xhr.get(
      remoting.settings.DIRECTORY_API_BASE_URL + '/support-hosts/' +
          encodeURIComponent(this.hostId_),
      this.onIT2MeHostInfo_.bind(this),
      '',
      { 'Authorization': 'OAuth ' + token });
};

/**
 * Continue an IT2Me connection once the host JID has been looked up.
 *
 * @param {XMLHttpRequest} xhr The server response to the support-hosts query.
 * @return {void} Nothing.
 * @private
 */
remoting.SessionConnector.prototype.onIT2MeHostInfo_ = function(xhr) {
  this.pendingXhr_ = null;
  if (xhr.status == 200) {
    var host = /** @type {{data: {jabberId: string, publicKey: string}}} */
        jsonParseSafe(xhr.responseText);
    if (host && host.data && host.data.jabberId && host.data.publicKey) {
      this.hostJid_ = host.data.jabberId;
      this.hostPublicKey_ = host.data.publicKey;
      this.hostDisplayName_ = this.hostJid_.split('/')[0];
      this.createSession_();
      return;
    } else {
      console.error('Invalid "support-hosts" response from server.');
    }
  } else {
    this.onError_(this.translateSupportHostsError(xhr.status));
  }
};

/**
 * Creates ClientSession object.
 */
remoting.SessionConnector.prototype.createSession_ = function() {
  // In some circumstances, the WCS <iframe> can get reloaded, which results
  // in a new clientJid and a new callback. In this case, remove the old
  // client plugin before instantiating a new one.
  if (this.clientSession_) {
    this.clientSession_.removePlugin();
    this.clientSession_ = null;
  }

  var authenticationMethods =
     'third_party,spake2_pair,spake2_hmac,spake2_plain';
  this.clientSession_ = new remoting.ClientSession(
      this.passPhrase_, this.fetchPin_, this.fetchThirdPartyToken_,
      authenticationMethods, this.hostId_, this.hostJid_, this.hostPublicKey_,
      this.connectionMode_, this.clientPairingId_, this.clientPairedSecret_);
  this.clientSession_.logHostOfflineErrors(!this.refreshHostJidIfOffline_);
  this.clientSession_.setOnStateChange(this.onStateChange_.bind(this));
  this.clientSession_.createPluginAndConnect(this.pluginParent_);
};

/**
 * Handle a change in the state of the client session prior to successful
 * connection (after connection, this class no longer handles state change
 * events). Errors that occur while connecting either trigger a reconnect
 * or notify the onError handler.
 *
 * @param {number} oldState The previous state of the plugin.
 * @param {number} newState The current state of the plugin.
 * @return {void} Nothing.
 * @private
 */
remoting.SessionConnector.prototype.onStateChange_ =
    function(oldState, newState) {
  switch (newState) {
    case remoting.ClientSession.State.CONNECTED:
      // When the connection succeeds, deregister for state-change callbacks
      // and pass the session to the onOk callback. It is expected that it
      // will register a new state-change callback to handle disconnect
      // or error conditions.
      this.clientSession_.setOnStateChange(null);
      this.onOk_(this.clientSession_);
      break;

    case remoting.ClientSession.State.CREATED:
      console.log('Created plugin');
      break;

    case remoting.ClientSession.State.CONNECTING:
      console.log('Connecting as ' + remoting.identity.getCachedEmail());
      break;

    case remoting.ClientSession.State.INITIALIZING:
      console.log('Initializing connection');
      break;

    case remoting.ClientSession.State.CLOSED:
      // This class deregisters for state-change callbacks when the CONNECTED
      // state is reached, so it only sees the CLOSED state in exceptional
      // circumstances. For example, a CONNECTING -> CLOSED transition happens
      // if the host closes the connection without an error message instead of
      // accepting it. Since there's no way of knowing exactly what went wrong,
      // we rely on server-side logs in this case and report a generic error
      // message.
      this.onError_(remoting.Error.UNEXPECTED);
      break;

    case remoting.ClientSession.State.FAILED:
      var error = this.clientSession_.getError();
      console.error('Client plugin reported connection failed: ' + error);
      if (error == null) {
        error = remoting.Error.UNEXPECTED;
      }
      if (error == remoting.Error.HOST_IS_OFFLINE &&
          this.refreshHostJidIfOffline_) {
        remoting.hostList.refresh(this.onHostListRefresh_.bind(this));
      } else {
        this.onError_(error);
      }
      break;

    default:
      console.error('Unexpected client plugin state: ' + newState);
      // This should only happen if the web-app and client plugin get out of
      // sync, and even then the version check should ensure compatibility.
      this.onError_(remoting.Error.MISSING_PLUGIN);
  }
};

/**
 * @param {boolean} success True if the host list was successfully refreshed;
 *     false if an error occurred.
 * @private
 */
remoting.SessionConnector.prototype.onHostListRefresh_ = function(success) {
  if (success) {
    var host = remoting.hostList.getHostForId(this.hostId_);
    if (host) {
      this.connectMe2MeInternal_(
          host.hostId, host.jabberId, host.publicKey, host.hostName,
          this.fetchPin_, this.fetchThirdPartyToken_,
          this.clientPairingId_, this.clientPairedSecret_, false);
      return;
    }
  }
  this.onError_(remoting.Error.HOST_IS_OFFLINE);
};

/**
 * @param {number} error An HTTP error code returned by the support-hosts
 *     endpoint.
 * @return {remoting.Error} The equivalent remoting.Error code.
 * @private
 */
remoting.SessionConnector.prototype.translateSupportHostsError =
    function(error) {
  switch (error) {
    case 0: return remoting.Error.NETWORK_FAILURE;
    case 404: return remoting.Error.INVALID_ACCESS_CODE;
    case 502: // No break
    case 503: return remoting.Error.SERVICE_UNAVAILABLE;
    default: return remoting.Error.UNEXPECTED;
  }
};

/**
 * Normalize the access code entered by the user.
 *
 * @param {string} accessCode The access code, as entered by the user.
 * @return {string} The normalized form of the code (whitespace removed).
 */
remoting.SessionConnector.prototype.normalizeAccessCode_ =
    function(accessCode) {
  // Trim whitespace.
  return accessCode.replace(/\s/g, '');
};
