// Copyright (c) 2012 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
 * Class representing the host-list portion of the home screen UI.
 */

'use strict';

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

/**
 * Create a host list consisting of the specified HTML elements, which should
 * have a common parent that contains only host-list UI as it will be hidden
 * if the host-list is empty.
 *
 * @constructor
 * @param {Element} table The HTML <div> to contain host-list.
 * @param {Element} noHosts The HTML <div> containing the "no hosts" message.
 * @param {Element} errorMsg The HTML <div> to display error messages.
 * @param {Element} errorButton The HTML <button> to display the error
 *     resolution action.
 * @param {HTMLElement} loadingIndicator The HTML <span> to update while the
 *     host list is being loaded. The first element of this span should be
 *     the reload button.
 */
remoting.HostList = function(table, noHosts, errorMsg, errorButton,
                             loadingIndicator) {
  /**
   * @type {Element}
   * @private
   */
  this.table_ = table;
  /**
   * @type {Element}
   * @private
   * TODO(jamiewalch): This should be doable using CSS's sibling selector,
   * but it doesn't work right now (crbug.com/135050).
   */
  this.noHosts_ = noHosts;
  /**
   * @type {Element}
   * @private
   */
  this.errorMsg_ = errorMsg;
  /**
   * @type {Element}
   * @private
   */
  this.errorButton_ = errorButton;
  /**
   * @type {HTMLElement}
   * @private
   */
  this.loadingIndicator_ = loadingIndicator;
  /**
   * @type {Array.<remoting.HostTableEntry>}
   * @private
   */
  this.hostTableEntries_ = [];
  /**
   * @type {Array.<remoting.Host>}
   * @private
   */
  this.hosts_ = [];
  /**
   * @type {string}
   * @private
   */
  this.lastError_ = '';
  /**
   * @type {remoting.Host?}
   * @private
   */
  this.localHost_ = null;
  /**
   * @type {remoting.HostController.State}
   * @private
   */
  this.localHostState_ = remoting.HostController.State.NOT_IMPLEMENTED;
  /**
   * @type {number}
   * @private
   */
  this.webappMajorVersion_ = parseInt(chrome.runtime.getManifest().version, 10);

  this.errorButton_.addEventListener('click',
                                     this.onErrorClick_.bind(this),
                                     false);
  var reloadButton = this.loadingIndicator_.firstElementChild;
  /** @type {remoting.HostList} */
  var that = this;
  /** @param {Event} event */
  function refresh(event) {
    event.preventDefault();
    that.refresh(that.display.bind(that));
  };
  reloadButton.addEventListener('click', refresh, false);
};

/**
 * Load the host-list asynchronously from local storage.
 *
 * @param {function():void} onDone Completion callback.
 */
remoting.HostList.prototype.load = function(onDone) {
  // Load the cache of the last host-list, if present.
  /** @type {remoting.HostList} */
  var that = this;
  /** @param {Object.<string>} items */
  var storeHostList = function(items) {
    if (items[remoting.HostList.HOSTS_KEY]) {
      var cached = jsonParseSafe(items[remoting.HostList.HOSTS_KEY]);
      if (cached) {
        that.hosts_ = /** @type {Array} */ cached;
      } else {
        console.error('Invalid value for ' + remoting.HostList.HOSTS_KEY);
      }
    }
    onDone();
  };
  chrome.storage.local.get(remoting.HostList.HOSTS_KEY, storeHostList);
};

/**
 * Search the host list for a host with the specified id.
 *
 * @param {string} hostId The unique id of the host.
 * @return {remoting.Host?} The host, if any.
 */
remoting.HostList.prototype.getHostForId = function(hostId) {
  for (var i = 0; i < this.hosts_.length; ++i) {
    if (this.hosts_[i].hostId == hostId) {
      return this.hosts_[i];
    }
  }
  return null;
};

/**
 * Get the host id corresponding to the specified host name.
 *
 * @param {string} hostName The name of the host.
 * @return {string?} The host id, if a host with the given name exists.
 */
remoting.HostList.prototype.getHostIdForName = function(hostName) {
  for (var i = 0; i < this.hosts_.length; ++i) {
    if (this.hosts_[i].hostName == hostName) {
      return this.hosts_[i].hostId;
    }
  }
  return null;
};

/**
 * Query the Remoting Directory for the user's list of hosts.
 *
 * @param {function(boolean):void} onDone Callback invoked with true on success
 *     or false on failure.
 * @return {void} Nothing.
 */
remoting.HostList.prototype.refresh = function(onDone) {
  this.loadingIndicator_.classList.add('loading');
  /** @param {XMLHttpRequest} xhr The response from the server. */
  var parseHostListResponse = this.parseHostListResponse_.bind(this, onDone);
  /** @type {remoting.HostList} */
  var that = this;
  /** @param {string} token The OAuth2 token. */
  var getHosts = function(token) {
    var headers = { 'Authorization': 'OAuth ' + token };
    remoting.xhr.get(
        remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts',
        parseHostListResponse, '', headers);
  };
  /** @param {remoting.Error} error */
  var onError = function(error) {
    that.lastError_ = error;
    onDone(false);
  };
  remoting.identity.callWithToken(getHosts, onError);
};

/**
 * Handle the results of the host list request.  A success response will
 * include a JSON-encoded list of host descriptions, which we display if we're
 * able to successfully parse it.
 *
 * @param {function(boolean):void} onDone The callback passed to |refresh|.
 * @param {XMLHttpRequest} xhr The XHR object for the host list request.
 * @return {void} Nothing.
 * @private
 */
remoting.HostList.prototype.parseHostListResponse_ = function(onDone, xhr) {
  this.lastError_ = '';
  try {
    if (xhr.status == 200) {
      var response =
          /** @type {{data: {items: Array}}} */ jsonParseSafe(xhr.responseText);
      if (response && response.data) {
        if (response.data.items) {
          this.hosts_ = response.data.items;
          /**
           * @param {remoting.Host} a
           * @param {remoting.Host} b
           */
          var cmp = function(a, b) {
            if (a.status < b.status) {
              return 1;
            } else if (b.status < a.status) {
              return -1;
            }
            return 0;
          };
          this.hosts_ = /** @type {Array} */ this.hosts_.sort(cmp);
        } else {
          this.hosts_ = [];
        }
      } else {
        this.lastError_ = remoting.Error.UNEXPECTED;
        console.error('Invalid "hosts" response from server.');
      }
    } else {
      // Some other error.
      console.error('Bad status on host list query: ', xhr);
      if (xhr.status == 0) {
        this.lastError_ = remoting.Error.NETWORK_FAILURE;
      } else if (xhr.status == 401) {
        this.lastError_ = remoting.Error.AUTHENTICATION_FAILED;
      } else if (xhr.status == 502 || xhr.status == 503) {
        this.lastError_ = remoting.Error.SERVICE_UNAVAILABLE;
      } else {
        this.lastError_ = remoting.Error.UNEXPECTED;
      }
    }
  } catch (er) {
    var typed_er = /** @type {Object} */ (er);
    console.error('Error processing response: ', xhr, typed_er);
    this.lastError_ = remoting.Error.UNEXPECTED;
  }
  this.save_();
  this.loadingIndicator_.classList.remove('loading');
  onDone(this.lastError_ == '');
};

/**
 * Display the list of hosts or error condition.
 *
 * @return {void} Nothing.
 */
remoting.HostList.prototype.display = function() {
  this.table_.innerText = '';
  this.errorMsg_.innerText = '';
  this.hostTableEntries_ = [];

  var noHostsRegistered = (this.hosts_.length == 0);
  this.table_.hidden = noHostsRegistered;
  this.noHosts_.hidden = !noHostsRegistered;

  if (this.lastError_ != '') {
    l10n.localizeElementFromTag(this.errorMsg_, this.lastError_);
    if (this.lastError_ == remoting.Error.AUTHENTICATION_FAILED) {
      l10n.localizeElementFromTag(this.errorButton_,
                                  /*i18n-content*/'SIGN_IN_BUTTON');
    } else {
      l10n.localizeElementFromTag(this.errorButton_,
                                  /*i18n-content*/'RETRY');
    }
  } else {
    for (var i = 0; i < this.hosts_.length; ++i) {
      /** @type {remoting.Host} */
      var host = this.hosts_[i];
      // Validate the entry to make sure it has all the fields we expect and is
      // not the local host (which is displayed separately). NB: if the host has
      // never sent a heartbeat, then there will be no jabberId.
      if (host.hostName && host.hostId && host.status && host.publicKey &&
          (!this.localHost_ || host.hostId != this.localHost_.hostId)) {
        var hostTableEntry = new remoting.HostTableEntry(
            host, this.webappMajorVersion_,
            this.renameHost_.bind(this), this.deleteHost_.bind(this));
        hostTableEntry.createDom();
        this.hostTableEntries_[i] = hostTableEntry;
        this.table_.appendChild(hostTableEntry.tableRow);
      }
    }
  }

  this.errorMsg_.parentNode.hidden = (this.lastError_ == '');

  // The local host cannot be stopped or started if the host controller is not
  // implemented for this platform. Additionally, it cannot be started if there
  // is an error (in many error states, the start operation will fail anyway,
  // but even if it succeeds, the chance of a related but hard-to-diagnose
  // future error is high).
  var state = this.localHostState_;
  var enabled = (state == remoting.HostController.State.STARTING) ||
      (state == remoting.HostController.State.STARTED);
  var canChangeLocalHostState =
      (state != remoting.HostController.State.NOT_IMPLEMENTED) &&
      (enabled || this.lastError_ == '');

  remoting.updateModalUi(enabled ? 'enabled' : 'disabled', 'data-daemon-state');
  var element = document.getElementById('daemon-control');
  element.hidden = !canChangeLocalHostState;
  element = document.getElementById('host-list-empty-hosting-supported');
  element.hidden = !canChangeLocalHostState;
  element = document.getElementById('host-list-empty-hosting-unsupported');
  element.hidden = canChangeLocalHostState;
};

/**
 * Remove a host from the list, and deregister it.
 * @param {remoting.HostTableEntry} hostTableEntry The host to be removed.
 * @return {void} Nothing.
 * @private
 */
remoting.HostList.prototype.deleteHost_ = function(hostTableEntry) {
  this.table_.removeChild(hostTableEntry.tableRow);
  var index = this.hostTableEntries_.indexOf(hostTableEntry);
  if (index != -1) {
    this.hostTableEntries_.splice(index, 1);
  }
  remoting.HostList.unregisterHostById(hostTableEntry.host.hostId);
};

/**
 * Prepare a host for renaming by replacing its name with an edit box.
 * @param {remoting.HostTableEntry} hostTableEntry The host to be renamed.
 * @return {void} Nothing.
 * @private
 */
remoting.HostList.prototype.renameHost_ = function(hostTableEntry) {
  for (var i = 0; i < this.hosts_.length; ++i) {
    if (this.hosts_[i].hostId == hostTableEntry.host.hostId) {
      this.hosts_[i].hostName = hostTableEntry.host.hostName;
      break;
    }
  }
  this.save_();

  /** @param {string?} token */
  var renameHost = function(token) {
    if (token) {
      var headers = {
        'Authorization': 'OAuth ' + token,
        'Content-type' : 'application/json; charset=UTF-8'
      };
      var newHostDetails = { data: {
        hostId: hostTableEntry.host.hostId,
        hostName: hostTableEntry.host.hostName,
        publicKey: hostTableEntry.host.publicKey
      } };
      remoting.xhr.put(
          remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts/' +
          hostTableEntry.host.hostId,
          function(xhr) {},
          JSON.stringify(newHostDetails),
          headers);
    } else {
      console.error('Could not rename host. Authentication failure.');
    }
  }
  remoting.identity.callWithToken(renameHost, remoting.showErrorMessage);
};

/**
 * Unregister a host.
 * @param {string} hostId The id of the host to be removed.
 * @return {void} Nothing.
 */
remoting.HostList.unregisterHostById = function(hostId) {
  /** @param {string} token The OAuth2 token. */
  var deleteHost = function(token) {
    var headers = { 'Authorization': 'OAuth ' + token };
    remoting.xhr.remove(
        remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts/' + hostId,
        function() {}, '', headers);
  }
  remoting.identity.callWithToken(deleteHost, remoting.showErrorMessage);
};

/**
 * Set tool-tips for the 'connect' action. We can't just set this on the
 * parent element because the button has no tool-tip, and therefore would
 * inherit connectStr.
 *
 * @return {void} Nothing.
 * @private
 */
remoting.HostList.prototype.setTooltips_ = function() {
  var connectStr = '';
  if (this.localHost_) {
    chrome.i18n.getMessage(/*i18n-content*/'TOOLTIP_CONNECT',
                           this.localHost_.hostName);
  }
  document.getElementById('this-host-name').title = connectStr;
  document.getElementById('this-host-icon').title = connectStr;
};

/**
 * Set the state of the local host and localHostId if any.
 *
 * @param {remoting.HostController.State} state State of the local host.
 * @param {string?} hostId ID of the local host, or null.
 * @return {void} Nothing.
 */
remoting.HostList.prototype.setLocalHostStateAndId = function(state, hostId) {
  this.localHostState_ = state;
  this.setLocalHost_(hostId ? this.getHostForId(hostId) : null);
}

/**
 * Set the host object that corresponds to the local computer, if any.
 *
 * @param {remoting.Host?} host The host, or null if not registered.
 * @return {void} Nothing.
 * @private
 */
remoting.HostList.prototype.setLocalHost_ = function(host) {
  this.localHost_ = host;
  this.setTooltips_();
  /** @type {remoting.HostList} */
  var that = this;
  if (host) {
    /** @param {remoting.HostTableEntry} host */
    var renameHost = function(host) {
      that.renameHost_(host);
      that.setTooltips_();
    };
    if (!this.localHostTableEntry_) {
      /** @type {remoting.HostTableEntry} @private */
      this.localHostTableEntry_ = new remoting.HostTableEntry(
          host, this.webappMajorVersion_, renameHost);
      this.localHostTableEntry_.init(
          document.getElementById('this-host-connect'),
          document.getElementById('this-host-warning'),
          document.getElementById('this-host-name'),
          document.getElementById('this-host-rename'));
    } else {
      // TODO(jamiewalch): This is hack to prevent multiple click handlers being
      // registered for the same DOM elements if this method is called more than
      // once. A better solution would be to let HostTable create the daemon row
      // like it creates the rows for non-local hosts.
      this.localHostTableEntry_.host = host;
    }
  } else {
    this.localHostTableEntry_ = null;
  }
}

/**
 * Called by the HostControlled after the local host has been started.
 *
 * @param {string} hostName Host name.
 * @param {string} hostId ID of the local host.
 * @param {string} publicKey Public key.
 * @return {void} Nothing.
 */
remoting.HostList.prototype.onLocalHostStarted = function(
    hostName, hostId, publicKey) {
  // Create a dummy remoting.Host instance to represent the local host.
  // Refreshing the list is no good in general, because the directory
  // information won't be in sync for several seconds. We don't know the
  // host JID, but it can be missing from the cache with no ill effects.
  // It will be refreshed if the user tries to connect to the local host,
  // and we hope that the directory will have been updated by that point.
  var localHost = new remoting.Host();
  localHost.hostName = hostName;
  // Provide a version number to avoid warning about this dummy host being
  // out-of-date.
  localHost.hostVersion = String(this.webappMajorVersion_) + ".x"
  localHost.hostId = hostId;
  localHost.publicKey = publicKey;
  localHost.status = 'ONLINE';
  this.hosts_.push(localHost);
  this.save_();
  this.setLocalHost_(localHost);
};

/**
 * Called when the user clicks the button next to the error message. The action
 * depends on the error.
 *
 * @private
 */
remoting.HostList.prototype.onErrorClick_ = function() {
  if (this.lastError_ == remoting.Error.AUTHENTICATION_FAILED) {
    remoting.oauth2.doAuthRedirect();
  } else {
    this.refresh(remoting.updateLocalHostState);
  }
};

/**
 * Save the host list to local storage.
 */
remoting.HostList.prototype.save_ = function() {
  var items = {};
  items[remoting.HostList.HOSTS_KEY] = JSON.stringify(this.hosts_);
  chrome.storage.local.set(items);
};

/**
 * Key name under which Me2Me hosts are cached.
 */
remoting.HostList.HOSTS_KEY = 'me2me-cached-hosts';

/** @type {remoting.HostList} */
remoting.hostList = null;
