// Copyright (c) 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.

'use strict';

/**
 * SuggestAppsDialog contains a list box to select an app to be opened the file
 * with. This dialog should be used as action picker for file operations.
 */

/**
 * The width of the widget (in pixel).
 * @type {number}
 * @const
 */
var WEBVIEW_WIDTH = 735;
/**
 * The height of the widget (in pixel).
 * @type {number}
 * @const
 */
var WEBVIEW_HEIGHT = 480;

/**
 * The URL of the widget.
 * @type {string}
 * @const
 */
var CWS_WIDGET_URL =
    'https://clients5.google.com/webstore/wall/cros-widget-container';
/**
 * The origin of the widget.
 * @type {string}
 * @const
 */
var CWS_WIDGET_ORIGIN = 'https://clients5.google.com';

/**
 * Creates dialog in DOM tree.
 *
 * @param {HTMLElement} parentNode Node to be parent for this dialog.
 * @param {Object} state Static state of suggest app dialog.
 * @constructor
 * @extends {FileManagerDialogBase}
 */
function SuggestAppsDialog(parentNode, state) {
  FileManagerDialogBase.call(this, parentNode);

  this.frame_.id = 'suggest-app-dialog';

  this.spinner_ = this.document_.createElement('div');
  this.spinner_.className = 'spinner';

  this.spinnerWrapper_ = this.document_.createElement('div');
  this.spinnerWrapper_.className = 'spinner-container';
  this.spinnerWrapper_.style.width = WEBVIEW_WIDTH + 'px';
  this.spinnerWrapper_.style.height = WEBVIEW_HEIGHT + 'px';
  this.spinnerWrapper_.appendChild(this.spinner_);
  this.frame_.insertBefore(this.spinnerWrapper_, this.text_.nextSibling);

  this.webviewContainer_ = this.document_.createElement('div');
  this.webviewContainer_.id = 'webview-container';
  this.webviewContainer_.style.width = WEBVIEW_WIDTH + 'px';
  this.webviewContainer_.style.height = WEBVIEW_HEIGHT + 'px';
  this.frame_.insertBefore(this.webviewContainer_, this.text_.nextSibling);

  this.buttons_ = this.document_.createElement('div');
  this.buttons_.id = 'buttons';
  this.frame_.appendChild(this.buttons_);

  this.webstoreButton_ = this.document_.createElement('div');
  this.webstoreButton_.id = 'webstore-button';
  this.webstoreButton_.innerHTML = str('SUGGEST_DIALOG_LINK_TO_WEBSTORE');
  this.webstoreButton_.addEventListener(
      'click', this.onWebstoreLinkClicked_.bind(this));
  this.buttons_.appendChild(this.webstoreButton_);

  this.initialFocusElement_ = this.webviewContainer_;

  this.webview_ = null;
  this.accessToken_ = null;
  this.widgetUrl_ =
      state.overrideCwsContainerUrlForTest || CWS_WIDGET_URL;
  this.widgetOrigin_ =
      state.overrideCwsContainerOriginForTest || CWS_WIDGET_ORIGIN;

  this.extension_ = null;
  this.mime_ = null;
  this.installingItemId_ = null;
  this.state_ = SuggestAppsDialog.State.UNINITIALIZED;

  this.initializationTask_ = new AsyncUtil.Group();
  this.initializationTask_.add(this.retrieveAuthorizeToken_.bind(this));
  this.initializationTask_.run();
}

SuggestAppsDialog.prototype = {
  __proto__: FileManagerDialogBase.prototype
};

/**
 * @enum {string}
 * @const
 */
SuggestAppsDialog.State = {
  UNINITIALIZED: 'SuggestAppsDialog.State.UNINITIALIZED',
  INITIALIZING: 'SuggestAppsDialog.State.INITIALIZING',
  INITIALIZE_FAILED_CLOSING:
      'SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING',
  INITIALIZED: 'SuggestAppsDialog.State.INITIALIZED',
  INSTALLING: 'SuggestAppsDialog.State.INSTALLING',
  INSTALLED_CLOSING: 'SuggestAppsDialog.State.INSTALLED_CLOSING',
  CANCELED_CLOSING: 'SuggestAppsDialog.State.CANCELED_CLOSING'
};
Object.freeze(SuggestAppsDialog.State);

/**
 * @enum {string}
 * @const
 */
SuggestAppsDialog.Result = {
  // Install is done. The install app should be opened.
  INSTALL_SUCCESSFUL: 'SuggestAppsDialog.Result.INSTALL_SUCCESSFUL',
  // User cancelled the suggest app dialog. No message should be shown.
  USER_CANCELL: 'SuggestAppsDialog.Result.USER_CANCELL',
  // Failed to load the widget. Error message should be shown.
  FAILED: 'SuggestAppsDialog.Result.FAILED'
};
Object.freeze(SuggestAppsDialog.Result);

/**
 * @override
 */
SuggestAppsDialog.prototype.onInputFocus = function() {
  this.webviewContainer_.select();
};

/**
 * Injects headers into the passed request.
 *
 * @param {Event} e Request event.
 * @return {{requestHeaders: HttpHeaders}} Modified headers.
 * @private
 */
SuggestAppsDialog.prototype.authorizeRequest_ = function(e) {
  e.requestHeaders.push({
    name: 'Authorization',
    value: 'Bearer ' + this.accessToken_
  });
  return {requestHeaders: e.requestHeaders};
};

/**
 * Retrieves the authorize token. This method should be called in
 * initialization of the dialog.
 *
 * @param {function()} callback Called when the token is retrieved.
 * @private
 */
SuggestAppsDialog.prototype.retrieveAuthorizeToken_ = function(callback) {
  if (window.IN_TEST) {
    // In test, use a dummy string as token. This must be a non-empty string.
    this.accessToken_ = 'DUMMY_ACCESS_TOKEN_FOR_TEST';
  }

  if (this.accessToken_) {
    callback();
    return;
  }

  // Fetch or update the access token.
  chrome.fileBrowserPrivate.requestWebStoreAccessToken(
      function(accessToken) {
        // In case of error, this.accessToken_ will be set to null.
        this.accessToken_ = accessToken;
        callback();
      }.bind(this));
};

/**
 * Shows dialog.
 *
 * @param {string} extension Extension of the file.
 * @param {string} mime Mime of the file.
 * @param {function(boolean)} onDialogClosed Called when the dialog is closed.
 *     The argument is the result of installation: true if an app is installed,
 *     false otherwise.
 */
SuggestAppsDialog.prototype.show = function(extension, mime, onDialogClosed) {
  if (this.state_ != SuggestAppsDialog.State.UNINITIALIZED) {
    console.error('Invalid state.');
    return;
  }

  this.extension_ = extension;
  this.mimeType_ = mime;
  this.onDialogClosed_ = onDialogClosed;
  this.state_ = SuggestAppsDialog.State.INITIALIZING;

  // Makes it sure that the initialization is completed.
  this.initializationTask_.run(function() {
    if (!this.accessToken_) {
      this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
      this.onHide_();
      return;
    }

    var title = str('SUGGEST_DIALOG_TITLE');

    var show =
        FileManagerDialogBase.prototype.showTitleOnlyDialog.call(this, title);
    if (!show) {
      console.error('SuggestAppsDialog can\'t be shown');
      this.state_ = SuggestAppsDialog.State.UNINITIALIZED;
      this.onHide();
      return;
    }

    this.webviewContainer_.innerHTML =
        '<webview id="cws-widget" partition="persist:cwswidgets"></webview>';

    this.webview_ = this.container_.querySelector('#cws-widget');
    this.webview_.style.width = WEBVIEW_WIDTH + 'px';
    this.webview_.style.height = WEBVIEW_HEIGHT + 'px';
    this.webview_.request.onBeforeSendHeaders.addListener(
        this.authorizeRequest_.bind(this),
        {urls: [this.widgetOrigin_ + '/*']},
        ['blocking', 'requestHeaders']);
    this.webview_.addEventListener('newwindow', function(event) {
      // Discard the window object and reopen in an external window.
      event.window.discard();
      util.visitURL(event.targetUrl);
      event.preventDefault();
    });

    this.frame_.classList.add('show-spinner');

    this.webviewClient_ = new CWSContainerClient(
        this.webview_,
        extension, mime,
        WEBVIEW_WIDTH, WEBVIEW_HEIGHT,
        this.widgetUrl_, this.widgetOrigin_);
    this.webviewClient_.addEventListener(CWSContainerClient.Events.LOADED,
                                         this.onWidgetLoaded_.bind(this));
    this.webviewClient_.addEventListener(CWSContainerClient.Events.LOAD_FAILED,
                                         this.onWidgetLoadFailed_.bind(this));
    this.webviewClient_.addEventListener(
        CWSContainerClient.Events.REQUEST_INSTALL,
        this.onInstallRequest_.bind(this));
    this.webviewClient_.load();
  }.bind(this));
};

/**
 * Called when the 'See more...' link is clicked to be navigated to Webstore.
 * @param {Event} e Event.
 * @private
 */
SuggestAppsDialog.prototype.onWebstoreLinkClicked_ = function(e) {
  var webStoreUrl =
      FileTasks.createWebStoreLink(this.extension_, this.mimeType_);
  chrome.windows.create({url: webStoreUrl});
  this.hide();
};

/**
 * Called when the widget is loaded successfully.
 * @param {Event} event Event.
 * @private
 */
SuggestAppsDialog.prototype.onWidgetLoaded_ = function(event) {
  this.frame_.classList.remove('show-spinner');
  this.state_ = SuggestAppsDialog.State.INITIALIZED;

  this.webview_.focus();
};

/**
 * Called when the widget is failed to load.
 * @param {Event} event Event.
 * @private
 */
SuggestAppsDialog.prototype.onWidgetLoadFailed_ = function(event) {
  this.frame_.classList.remove('show-spinner');
  this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;

  this.hide();
};

/**
 * Called when the connection status is changed.
 * @param {util.DriveConnectionType} connectionType Current connection type.
 */
SuggestAppsDialog.prototype.onDriveConnectionChanged =
    function(connectionType) {
  if (this.state_ !== SuggestAppsDialog.State.UNINITIALIZED &&
      connectionType === util.DriveConnectionType.OFFLINE) {
    this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
    this.hide();
  }
};

/**
 * Called when receiving the install request from the webview client.
 * @param {Event} e Event.
 * @private
 */
SuggestAppsDialog.prototype.onInstallRequest_ = function(e) {
  var itemId = e.itemId;
  this.installingItemId_ = itemId;

  this.appInstaller_ = new AppInstaller(itemId);
  this.appInstaller_.install(this.onInstallCompleted_.bind(this));

  this.frame_.classList.add('show-spinner');
  this.state_ = SuggestAppsDialog.State.INSTALLING;
};

/**
 * Called when the installation is completed from the app installer.
 * @param {AppInstaller.Result} result Result of the installation.
 * @param {string} error Detail of the error.
 * @private
 */
SuggestAppsDialog.prototype.onInstallCompleted_ = function(result, error) {
  var success = (result === AppInstaller.Result.SUCCESS);

  this.frame_.classList.remove('show-spinner');
  this.state_ = success ?
                SuggestAppsDialog.State.INSTALLED_CLOSING :
                SuggestAppsDialog.State.INITIALIZED;  // Back to normal state.
  this.webviewClient_.onInstallCompleted(success, this.installingItemId_);
  this.installingItemId_ = null;

  switch (result) {
  case AppInstaller.Result.SUCCESS:
    this.hide();
    break;
  case AppInstaller.Result.CANCELLED:
    // User cancelled the installation. Do nothing.
    break;
  case AppInstaller.Result.ERROR:
    fileManager.error.show(str('SUGGEST_DIALOG_INSTALLATION_FAILED'));
    break;
  }
};

/**
 * @override
 */
SuggestAppsDialog.prototype.hide = function(opt_originalOnHide) {
  switch (this.state_) {
    case SuggestAppsDialog.State.INSTALLING:
      // Install is being aborted. Send the failure result.
      // Cancels the install.
      if (this.webviewClient_)
        this.webviewClient_.onInstallCompleted(false, this.installingItemId_);
      this.installingItemId_ = null;

      // Assumes closing the dialog as canceling the install.
      this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
      break;
    case SuggestAppsDialog.State.INSTALLED_CLOSING:
    case SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING:
      // Do nothing.
      break;
    case SuggestAppsDialog.State.INITIALIZED:
      this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
      break;
    default:
      this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
      console.error('Invalid state.');
  }

  if (this.webviewClient_) {
    this.webviewClient_.dispose();
    this.webviewClient_ = null;
  }

  this.webviewContainer_.innerHTML = '';
  this.extension_ = null;
  this.mime_ = null;

  FileManagerDialogBase.prototype.hide.call(
      this,
      this.onHide_.bind(this, opt_originalOnHide));
};

/**
 * @param {function()=} opt_originalOnHide Original onHide function passed to
 *     SuggestAppsDialog.hide().
 * @private
 */
SuggestAppsDialog.prototype.onHide_ = function(opt_originalOnHide) {
  // Calls the callback after the dialog hides.
  if (opt_originalOnHide)
    opt_originalOnHide();

  var result;
  switch (this.state_) {
    case SuggestAppsDialog.State.INSTALLED_CLOSING:
      result = SuggestAppsDialog.Result.INSTALL_SUCCESSFUL;
      break;
    case SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING:
      result = SuggestAppsDialog.Result.FAILED;
      break;
    case SuggestAppsDialog.State.CANCELED_CLOSING:
      result = SuggestAppsDialog.Result.USER_CANCELL;
      break;
    default:
      result = SuggestAppsDialog.Result.USER_CANCELL;
      console.error('Invalid state.');
  }
  this.state_ = SuggestAppsDialog.State.UNINITIALIZED;

  this.onDialogClosed_(result);
};
