// Copyright 2015 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.

(function() {

/**
 * Names of the radio buttons which allow the user to choose their encryption
 * mechanism.
 * @enum {string}
 */
const RadioButtonNames = {
  ENCRYPT_WITH_GOOGLE: 'encrypt-with-google',
  ENCRYPT_WITH_PASSPHRASE: 'encrypt-with-passphrase',
};

/**
 * @fileoverview
 * 'settings-sync-page' is the settings page containing sync settings.
 */
Polymer({
  is: 'settings-sync-page',

  behaviors: [
    WebUIListenerBehavior,
    settings.RouteObserverBehavior,
  ],

  properties: {
    /**
     * Preferences state.
     */
    prefs: {
      type: Object,
      notify: true,
    },

    /** @private */
    pages_: {
      type: Object,
      value: settings.PageStatus,
      readOnly: true,
    },

    /**
     * The current page status. Defaults to |CONFIGURE| such that the searching
     * algorithm can search useful content when the page is not visible to the
     * user.
     * @private {?settings.PageStatus}
     */
    pageStatus_: {
      type: String,
      value: settings.PageStatus.CONFIGURE,
    },

    /**
     * Dictionary defining page visibility.
     * @type {!PrivacyPageVisibility}
     */
    pageVisibility: Object,

    /**
     * The current sync preferences, supplied by SyncBrowserProxy.
     * @type {settings.SyncPrefs|undefined}
     */
    syncPrefs: {
      type: Object,
    },

    /** @type {settings.SyncStatus} */
    syncStatus: {
      type: Object,
    },

    /**
     * Whether the "create passphrase" inputs should be shown. These inputs
     * give the user the opportunity to use a custom passphrase instead of
     * authenticating with their Google credentials.
     * @private
     */
    creatingNewPassphrase_: {
      type: Boolean,
      value: false,
    },

    /**
     * The passphrase input field value.
     * @private
     */
    passphrase_: {
      type: String,
      value: '',
    },

    /**
     * The passphrase confirmation input field value.
     * @private
     */
    confirmation_: {
      type: String,
      value: '',
    },

    /**
     * The existing passphrase input field value.
     * @private
     */
    existingPassphrase_: {
      type: String,
      value: '',
    },

    /** @private */
    signedIn_: {
      type: Boolean,
      value: true,
      computed: 'computeSignedIn_(syncStatus.signedIn)',
    },

    /** @private */
    syncDisabledByAdmin_: {
      type: Boolean,
      value: false,
      computed: 'computeSyncDisabledByAdmin_(syncStatus.managed)',
    },

    /** @private */
    syncSectionDisabled_: {
      type: Boolean,
      value: false,
      computed: 'computeSyncSectionDisabled_(' +
          'unifiedConsentEnabled, syncStatus.signedIn, syncStatus.disabled, ' +
          'syncStatus.hasError, syncStatus.statusAction)',
    },

    // <if expr="not chromeos">
    diceEnabled: Boolean,
    // </if>

    unifiedConsentEnabled: {
      type: Boolean,
      observer: 'initializeDidAbort_',
    },
  },

  /** @private {?settings.SyncBrowserProxy} */
  browserProxy_: null,

  /**
   * The unload callback is needed because the sign-in flow needs to know
   * if the user has closed the tab with the sync settings. This property is
   * non-null if the user is currently navigated on the sync settings route.
   *
   * TODO(crbug.com/862983): When unified consent is rolled out to 100% this
   * should be removed.
   *
   * @private {?Function}
   */
  beforeunloadCallback_: null,

  /**
   * Whether the initial layout for collapsible sections has been computed. It
   * is computed only once, the first time the sync status is updated.
   * @private {boolean}
   */
  collapsibleSectionsInitialized_: false,

  /**
   * Whether the user decided to abort sync. When unified consent is enabled,
   * this is initialized to true.
   * @private {boolean}
   */
  didAbort_: false,

  /** @override */
  created: function() {
    this.browserProxy_ = settings.SyncBrowserProxyImpl.getInstance();
  },

  /** @override */
  attached: function() {
    this.addWebUIListener(
        'page-status-changed', this.handlePageStatusChanged_.bind(this));
    this.addWebUIListener(
        'sync-prefs-changed', this.handleSyncPrefsChanged_.bind(this));

    if (settings.getCurrentRoute() == settings.routes.SYNC) {
      this.onNavigateToPage_();
    }
  },

  /** @override */
  detached: function() {
    if (settings.routes.SYNC.contains(settings.getCurrentRoute())) {
      this.onNavigateAwayFromPage_();
    }

    if (this.beforeunloadCallback_) {
      window.removeEventListener('beforeunload', this.beforeunloadCallback_);
      this.beforeunloadCallback_ = null;
    }
  },

  /**
   * @return {boolean}
   * @private
   */
  computeSignedIn_: function() {
    return !!this.syncStatus.signedIn;
  },

  /**
   * @return {boolean}
   * @private
   */
  computeSyncSectionDisabled_: function() {
    return !!this.unifiedConsentEnabled && this.syncStatus !== undefined &&
        (!this.syncStatus.signedIn || !!this.syncStatus.disabled ||
         (!!this.syncStatus.hasError &&
          this.syncStatus.statusAction !==
              settings.StatusAction.ENTER_PASSPHRASE));
  },

  /**
   * @return {boolean}
   * @private
   */
  computeSyncDisabledByAdmin_: function() {
    return this.syncStatus != undefined && !!this.syncStatus.managed;
  },

  /** @protected */
  currentRouteChanged: function() {
    if (settings.getCurrentRoute() == settings.routes.SYNC) {
      this.onNavigateToPage_();
    } else if (!settings.routes.SYNC.contains(settings.getCurrentRoute())) {
      this.onNavigateAwayFromPage_();
    }
  },

  /**
   * @param {!settings.PageStatus} expectedPageStatus
   * @return {boolean}
   * @private
   */
  isStatus_: function(expectedPageStatus) {
    return expectedPageStatus == this.pageStatus_;
  },

  /** @private */
  onNavigateToPage_: function() {
    assert(settings.getCurrentRoute() == settings.routes.SYNC);

    if (this.beforeunloadCallback_) {
      return;
    }

    this.collapsibleSectionsInitialized_ = false;

    // Display loading page until the settings have been retrieved.
    this.pageStatus_ = settings.PageStatus.SPINNER;

    this.browserProxy_.didNavigateToSyncPage();

    this.beforeunloadCallback_ = this.onNavigateAwayFromPage_.bind(this);
    window.addEventListener('beforeunload', this.beforeunloadCallback_);
  },

  /** @private */
  onNavigateAwayFromPage_: function() {
    if (!this.beforeunloadCallback_) {
      return;
    }

    // Reset the status to CONFIGURE such that the searching algorithm can
    // search useful content when the page is not visible to the user.
    this.pageStatus_ = settings.PageStatus.CONFIGURE;

    this.browserProxy_.didNavigateAwayFromSyncPage(this.didAbort_);
    this.initializeDidAbort_();

    window.removeEventListener('beforeunload', this.beforeunloadCallback_);
    this.beforeunloadCallback_ = null;
  },

  /**
   * Handler for when the sync preferences are updated.
   * @private
   */
  handleSyncPrefsChanged_: function(syncPrefs) {
    this.syncPrefs = syncPrefs;
    this.pageStatus_ = settings.PageStatus.CONFIGURE;

    // Hide the new passphrase box if the sync data has been encrypted.
    if (this.syncPrefs.encryptAllData) {
      this.creatingNewPassphrase_ = false;
    }

    // Focus the password input box if password is needed to start sync.
    if (this.syncPrefs.passphraseRequired) {
      // Wait for the dom-if templates to render and subpage to become visible.
      listenOnce(document, 'show-container', () => {
        const input = /** @type {!CrInputElement} */ (
            this.$$('#existingPassphraseInput'));
        if (!input.matches(':focus-within')) {
          input.focus();
        }
      });
    }
  },

  /** @private */
  onActivityControlsTap_: function() {
    this.browserProxy_.openActivityControlsUrl();
  },

  /**
   * @param {string} passphrase The passphrase input field value
   * @param {string} confirmation The passphrase confirmation input field value.
   * @return {boolean} Whether the passphrase save button should be enabled.
   * @private
   */
  isSaveNewPassphraseEnabled_: function(passphrase, confirmation) {
    return passphrase !== '' && confirmation !== '';
  },

  /**
   * Sends the newly created custom sync passphrase to the browser.
   * @private
   * @param {!Event} e
   */
  onSaveNewPassphraseTap_: function(e) {
    assert(this.creatingNewPassphrase_);

    // Ignore events on irrelevant elements or with irrelevant keys.
    if (e.target.tagName != 'PAPER-BUTTON' && e.target.tagName != 'CR-INPUT') {
      return;
    }
    if (e.type == 'keypress' && e.key != 'Enter') {
      return;
    }

    // If a new password has been entered but it is invalid, do not send the
    // sync state to the API.
    if (!this.validateCreatedPassphrases_()) {
      return;
    }

    this.syncPrefs.encryptAllData = true;
    this.syncPrefs.setNewPassphrase = true;
    this.syncPrefs.passphrase = this.passphrase_;

    this.browserProxy_.setSyncEncryption(this.syncPrefs)
        .then(this.handlePageStatusChanged_.bind(this));
  },

  /**
   * Sends the user-entered existing password to re-enable sync.
   * @private
   * @param {!Event} e
   */
  onSubmitExistingPassphraseTap_: function(e) {
    if (e.type == 'keypress' && e.key != 'Enter') {
      return;
    }

    assert(!this.creatingNewPassphrase_);

    this.syncPrefs.setNewPassphrase = false;

    this.syncPrefs.passphrase = this.existingPassphrase_;
    this.existingPassphrase_ = '';

    this.browserProxy_.setSyncEncryption(this.syncPrefs)
        .then(this.handlePageStatusChanged_.bind(this));
  },

  /**
   * Called when the page status updates.
   * @param {!settings.PageStatus} pageStatus
   * @private
   */
  handlePageStatusChanged_: function(pageStatus) {
    switch (pageStatus) {
      case settings.PageStatus.SPINNER:
      case settings.PageStatus.TIMEOUT:
      case settings.PageStatus.CONFIGURE:
        this.pageStatus_ = pageStatus;
        return;
      case settings.PageStatus.DONE:
        if (settings.getCurrentRoute() == settings.routes.SYNC) {
          settings.navigateTo(settings.routes.PEOPLE);
        }
        return;
      case settings.PageStatus.PASSPHRASE_FAILED:
        if (this.pageStatus_ == this.pages_.CONFIGURE && this.syncPrefs &&
            this.syncPrefs.passphraseRequired) {
          this.$$('#existingPassphraseInput').invalid = true;
        }
        return;
    }

    assertNotReached();
  },

  /**
   * Called when the encryption
   * @param {!Event} event
   * @private
   */
  onEncryptionRadioSelectionChanged_: function(event) {
    this.creatingNewPassphrase_ =
        event.detail.value == RadioButtonNames.ENCRYPT_WITH_PASSPHRASE;
  },

  /**
   * Computed binding returning the selected encryption radio button.
   * @private
   */
  selectedEncryptionRadio_: function() {
    return this.syncPrefs.encryptAllData || this.creatingNewPassphrase_ ?
        RadioButtonNames.ENCRYPT_WITH_PASSPHRASE :
        RadioButtonNames.ENCRYPT_WITH_GOOGLE;
  },

  /**
   * Computed binding returning text of the prompt for entering the passphrase.
   * @private
   */
  enterPassphrasePrompt_: function() {
    if (this.syncPrefs && this.syncPrefs.passphraseTypeIsCustom) {
      return this.syncPrefs.enterPassphraseBody;
    }

    return this.syncPrefs.enterGooglePassphraseBody;
  },

  /**
   * Checks the supplied passphrases to ensure that they are not empty and that
   * they match each other. Additionally, displays error UI if they are invalid.
   * @return {boolean} Whether the check was successful (i.e., that the
   *     passphrases were valid).
   * @private
   */
  validateCreatedPassphrases_: function() {
    const emptyPassphrase = !this.passphrase_;
    const mismatchedPassphrase = this.passphrase_ != this.confirmation_;

    this.$$('#passphraseInput').invalid = emptyPassphrase;
    this.$$('#passphraseConfirmationInput').invalid =
        !emptyPassphrase && mismatchedPassphrase;

    return !emptyPassphrase && !mismatchedPassphrase;
  },

  /**
   * @param {!Event} event
   * @private
   */
  onLearnMoreTap_: function(event) {
    if (event.target.tagName == 'A') {
      // Stop the propagation of events, so that clicking on links inside
      // checkboxes or radio buttons won't change the value.
      event.stopPropagation();
    }
  },

  /**
   * When unified-consent enabled, the non-toggle items on the bottom of sync
   * section should be wrapped with 'list-frame' in order to be indented
   * correctly.
   * @return {string}
   * @private
   */
  getListFrameClass_: function() {
    return this.unifiedConsentEnabled ? 'list-frame' : '';
  },

  /**
   * When unified-consent enabled, the non-toggle items on the bottom of sync
   * section will be wrapped with 'list-frame', and should have the 'list-item'
   * instead of 'settings-box' in order to be indented correctly.
   * @return {string}
   * @private
   */
  getListItemClass_: function() {
    return this.unifiedConsentEnabled ? 'list-item' : 'settings-box';
  },

  /**
   * When there is a sync passphrase, some items have an additional line for the
   * passphrase reset hint, making them three lines rather than two.
   * @return {string}
   * @private
   */
  getPassphraseHintLines_: function() {
    return this.syncPrefs.encryptAllData ? 'three-line' : 'two-line';
  },

  // <if expr="not chromeos">
  /**
   * @return {boolean}
   * @private
   */
  shouldShowSyncAccountControl_: function() {
    return !!this.unifiedConsentEnabled && this.syncStatus !== undefined &&
        !!this.syncStatus.syncSystemEnabled && !!this.syncStatus.signinAllowed;
  },
  // </if>

  /**
   * @return {boolean}
   * @private
   */
  shouldShowExistingPassphraseBelowAccount_: function() {
    return !!this.unifiedConsentEnabled && this.syncPrefs !== undefined &&
        !!this.syncPrefs.passphraseRequired;
  },

  /**
   * @return {boolean}
   * @private
   */
  shouldShowExistingPassphraseInSyncSection_: function() {
    return !this.unifiedConsentEnabled && this.syncPrefs !== undefined &&
        !!this.syncPrefs.passphraseRequired;
  },

  /** @private */
  onSyncAdvancedTap_: function() {
    settings.navigateTo(settings.routes.SYNC_ADVANCED);
  },

  /**
   * @return {boolean}
   * @private
   */
  shouldShowDriveSuggest_: function() {
    return loadTimeData.getBoolean('driveSuggestAvailable') &&
        !this.unifiedConsentEnabled;
  },

  /** @private */
  onSyncSetupCancel_: function() {
    this.didAbort_ = true;
    settings.navigateTo(settings.routes.BASIC);
  },

  /** @private */
  initializeDidAbort_: function() {
    this.didAbort_ = !!this.unifiedConsentEnabled;
  },

  /**
   * @param {!CustomEvent<boolean>} e The event passed from
   *     settings-sync-account-control.
   * @private
   */
  onSyncSetupDone_: function(e) {
    if (e.detail) {
      this.didAbort_ = false;
    }
    settings.navigateTo(settings.routes.BASIC);
  },
});

})();
