/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '@polymer/iron-input/iron-input';
import '@polymer/paper-toggle-button/paper-toggle-button';
import '../../../styles/gr-form-styles';
import '../../../styles/gr-menu-page-styles';
import '../../../styles/gr-page-nav-styles';
import '../../../styles/shared-styles';
import {
  applyTheme as applyDarkTheme,
  removeTheme as removeDarkTheme,
} from '../../../styles/themes/dark-theme';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../gr-change-table-editor/gr-change-table-editor';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-date-formatter/gr-date-formatter';
import '../../shared/gr-diff-preferences/gr-diff-preferences';
import '../../shared/gr-page-nav/gr-page-nav';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
import '../../shared/gr-select/gr-select';
import '../gr-account-info/gr-account-info';
import '../gr-agreements-list/gr-agreements-list';
import '../gr-edit-preferences/gr-edit-preferences';
import '../gr-email-editor/gr-email-editor';
import '../gr-gpg-editor/gr-gpg-editor';
import '../gr-group-list/gr-group-list';
import '../gr-http-password/gr-http-password';
import '../gr-identities/gr-identities';
import '../gr-menu-editor/gr-menu-editor';
import '../gr-ssh-editor/gr-ssh-editor';
import '../gr-watched-projects-editor/gr-watched-projects-editor';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-settings-view_html';
import {getDocsBaseUrl} from '../../../utils/url-util';
import {ChangeTableMixin} from '../../../mixins/gr-change-table-mixin/gr-change-table-mixin';
import {customElement, property, observe} from '@polymer/decorators';
import {AppElementParams} from '../../gr-app-types';
import {GrAccountInfo} from '../gr-account-info/gr-account-info';
import {GrWatchedProjectsEditor} from '../gr-watched-projects-editor/gr-watched-projects-editor';
import {GrGroupList} from '../gr-group-list/gr-group-list';
import {GrIdentities} from '../gr-identities/gr-identities';
import {GrEditPreferences} from '../gr-edit-preferences/gr-edit-preferences';
import {GrDiffPreferences} from '../../shared/gr-diff-preferences/gr-diff-preferences';
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
import {
  PreferencesInput,
  ServerInfo,
  TopMenuItemInfo,
} from '../../../types/common';
import {GrSshEditor} from '../gr-ssh-editor/gr-ssh-editor';
import {GrGpgEditor} from '../gr-gpg-editor/gr-gpg-editor';
import {GerritView} from '../../core/gr-navigation/gr-navigation';
import {GrEmailEditor} from '../gr-email-editor/gr-email-editor';
import {CustomKeyboardEvent} from '../../../types/events';
import {fire, EventType} from '../../../utils/event-util';

const PREFS_SECTION_FIELDS: Array<keyof PreferencesInput> = [
  'changes_per_page',
  'date_format',
  'time_format',
  'email_strategy',
  'diff_view',
  'publish_comments_on_push',
  'work_in_progress_by_default',
  'default_base_for_merges',
  'signed_off_by',
  'email_format',
  'size_bar_in_change_table',
  'relative_date_in_change_table',
];

const GERRIT_DOCS_BASE_URL =
  'https://gerrit-review.googlesource.com/' + 'Documentation';
const GERRIT_DOCS_FILTER_PATH = '/user-notify.html';
const ABSOLUTE_URL_PATTERN = /^https?:/;
const TRAILING_SLASH_PATTERN = /\/$/;

const HTTP_AUTH = ['HTTP', 'HTTP_LDAP'];

enum CopyPrefsDirection {
  PrefsToLocalPrefs,
  LocalPrefsToPrefs,
}

type LocalMenuItemInfo = Omit<TopMenuItemInfo, 'id'>;

export interface GrSettingsView {
  $: {
    restAPI: RestApiService & Element;
    accountInfo: GrAccountInfo;
    watchedProjectsEditor: GrWatchedProjectsEditor;
    groupList: GrGroupList;
    identities: GrIdentities;
    editPrefs: GrEditPreferences;
    diffPrefs: GrDiffPreferences;
    sshEditor: GrSshEditor;
    gpgEditor: GrGpgEditor;
    emailEditor: GrEmailEditor;
    insertSignedOff: HTMLInputElement;
    workInProgressByDefault: HTMLInputElement;
    showSizeBarsInFileList: HTMLInputElement;
    publishCommentsOnPush: HTMLInputElement;
    relativeDateInChangeTable: HTMLInputElement;
  };
}

@customElement('gr-settings-view')
export class GrSettingsView extends ChangeTableMixin(
  GestureEventListeners(LegacyElementMixin(PolymerElement))
) {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when the title of the page should change.
   *
   * @event title-change
   */

  /**
   * Fired with email confirmation text, or when the page reloads.
   *
   * @event show-alert
   */

  @property({type: Object})
  prefs: PreferencesInput = {};

  @property({type: Object})
  params?: AppElementParams;

  @property({type: Boolean})
  _accountInfoChanged?: boolean;

  @property({type: Array})
  _changeTableColumnsNotDisplayed?: string[];

  @property({type: Object})
  _localPrefs: PreferencesInput = {};

  @property({type: Array})
  _localChangeTableColumns: string[] = [];

  @property({type: Array})
  _localMenu: LocalMenuItemInfo[] = [];

  @property({type: Boolean})
  _loading = true;

  @property({type: Boolean})
  _changeTableChanged = false;

  @property({type: Boolean})
  _prefsChanged = false;

  @property({type: Boolean})
  _diffPrefsChanged?: boolean;

  @property({type: Boolean})
  _editPrefsChanged?: boolean;

  @property({type: Boolean})
  _menuChanged = false;

  @property({type: Boolean})
  _watchedProjectsChanged = false;

  @property({type: Boolean})
  _keysChanged = false;

  @property({type: Boolean})
  _gpgKeysChanged = false;

  @property({type: String})
  _newEmail?: string;

  @property({type: Boolean})
  _addingEmail = false;

  @property({type: String})
  _lastSentVerificationEmail?: string | null = null;

  @property({type: Object})
  _serverConfig?: ServerInfo;

  @property({type: String})
  _docsBaseUrl?: string | null;

  @property({type: Boolean})
  _emailsChanged?: boolean;

  @property({type: Boolean})
  _showNumber?: boolean;

  @property({type: Boolean})
  _isDark = false;

  public _testOnly_loadingPromise?: Promise<void>;

  /** @override */
  attached() {
    super.attached();
    // Polymer 2: anchor tag won't work on shadow DOM
    // we need to manually calling scrollIntoView when hash changed
    this.listen(window, 'location-change', '_handleLocationChange');
    this.dispatchEvent(
      new CustomEvent('title-change', {
        detail: {title: 'Settings'},
        composed: true,
        bubbles: true,
      })
    );

    this._isDark = !!window.localStorage.getItem('dark-theme');

    const promises: Array<Promise<unknown>> = [
      this.$.accountInfo.loadData(),
      this.$.watchedProjectsEditor.loadData(),
      this.$.groupList.loadData(),
      this.$.identities.loadData(),
      this.$.editPrefs.loadData(),
      this.$.diffPrefs.loadData(),
    ];

    promises.push(
      this.$.restAPI.getPreferences().then(prefs => {
        if (!prefs) {
          throw new Error('getPreferences returned undefined');
        }
        this.prefs = prefs;
        this._showNumber = !!prefs.legacycid_in_change_table;
        this._copyPrefs(CopyPrefsDirection.PrefsToLocalPrefs);
        this._cloneMenu(prefs.my);
        this._cloneChangeTableColumns(prefs.change_table);
      })
    );

    promises.push(
      this.$.restAPI.getConfig().then(config => {
        this._serverConfig = config;
        const configPromises: Array<Promise<void>> = [];

        if (this._serverConfig && this._serverConfig.sshd) {
          configPromises.push(this.$.sshEditor.loadData());
        }

        if (
          this._serverConfig &&
          this._serverConfig.receive &&
          this._serverConfig.receive.enable_signed_push
        ) {
          configPromises.push(this.$.gpgEditor.loadData());
        }

        configPromises.push(
          getDocsBaseUrl(config, this.$.restAPI).then(baseUrl => {
            this._docsBaseUrl = baseUrl;
          })
        );

        return Promise.all(configPromises);
      })
    );

    if (
      this.params &&
      this.params.view === GerritView.SETTINGS &&
      this.params.emailToken
    ) {
      promises.push(
        this.$.restAPI.confirmEmail(this.params.emailToken).then(message => {
          if (message) {
            fire(this, EventType.SHOW_ALERT, message);
          }
          this.$.emailEditor.loadData();
        })
      );
    } else {
      promises.push(this.$.emailEditor.loadData());
    }

    this._testOnly_loadingPromise = Promise.all(promises).then(() => {
      this._loading = false;

      // Handle anchor tag for initial load
      this._handleLocationChange();
    });
  }

  detached() {
    super.detached();
    this.unlisten(window, 'location-change', '_handleLocationChange');
  }

  _handleLocationChange() {
    // Handle anchor tag after dom attached
    const urlHash = window.location.hash;
    if (urlHash) {
      // Use shadowRoot for Polymer 2
      const elem = (this.shadowRoot || document).querySelector(urlHash);
      if (elem) {
        elem.scrollIntoView();
      }
    }
  }

  reloadAccountDetail() {
    Promise.all([this.$.accountInfo.loadData(), this.$.emailEditor.loadData()]);
  }

  _isLoading() {
    return this._loading || this._loading === undefined;
  }

  _copyPrefs(direction: CopyPrefsDirection) {
    let to;
    let from;
    if (direction === CopyPrefsDirection.LocalPrefsToPrefs) {
      from = this._localPrefs;
      to = 'prefs';
    } else {
      from = this.prefs;
      to = '_localPrefs';
    }
    for (let i = 0; i < PREFS_SECTION_FIELDS.length; i++) {
      this.set([to, PREFS_SECTION_FIELDS[i]], from[PREFS_SECTION_FIELDS[i]]);
    }
  }

  _cloneMenu(prefs: TopMenuItemInfo[]) {
    const menu = [];
    for (const item of prefs) {
      menu.push({
        name: item.name,
        url: item.url,
        target: item.target,
      });
    }
    this._localMenu = menu;
  }

  _cloneChangeTableColumns(changeTable: string[]) {
    let columns = this.getVisibleColumns(changeTable);

    if (columns.length === 0) {
      columns = this.columnNames;
      this._changeTableColumnsNotDisplayed = [];
    } else {
      this._changeTableColumnsNotDisplayed = this.getComplementColumns(
        changeTable
      );
    }
    this._localChangeTableColumns = columns;
  }

  @observe('_localChangeTableColumns', '_showNumber')
  _handleChangeTableChanged() {
    if (this._isLoading()) {
      return;
    }
    this._changeTableChanged = true;
  }

  @observe('_localPrefs.*')
  _handlePrefsChanged() {
    if (this._isLoading()) {
      return;
    }
    this._prefsChanged = true;
  }

  _handleRelativeDateInChangeTable() {
    this.set(
      '_localPrefs.relative_date_in_change_table',
      this.$.relativeDateInChangeTable.checked
    );
  }

  _handleShowSizeBarsInFileListChanged() {
    this.set(
      '_localPrefs.size_bar_in_change_table',
      this.$.showSizeBarsInFileList.checked
    );
  }

  _handlePublishCommentsOnPushChanged() {
    this.set(
      '_localPrefs.publish_comments_on_push',
      this.$.publishCommentsOnPush.checked
    );
  }

  _handleWorkInProgressByDefault() {
    this.set(
      '_localPrefs.work_in_progress_by_default',
      this.$.workInProgressByDefault.checked
    );
  }

  _handleInsertSignedOff() {
    this.set('_localPrefs.signed_off_by', this.$.insertSignedOff.checked);
  }

  @observe('_localMenu.splices')
  _handleMenuChanged() {
    if (this._isLoading()) {
      return;
    }
    this._menuChanged = true;
  }

  _handleSaveAccountInfo() {
    this.$.accountInfo.save();
  }

  _handleSavePreferences() {
    this._copyPrefs(CopyPrefsDirection.LocalPrefsToPrefs);

    return this.$.restAPI.savePreferences(this.prefs).then(() => {
      this._prefsChanged = false;
    });
  }

  _handleSaveChangeTable() {
    this.set('prefs.change_table', this._localChangeTableColumns);
    this.set('prefs.legacycid_in_change_table', this._showNumber);
    this._cloneChangeTableColumns(this._localChangeTableColumns);
    return this.$.restAPI.savePreferences(this.prefs).then(() => {
      this._changeTableChanged = false;
    });
  }

  _handleSaveDiffPreferences() {
    this.$.diffPrefs.save();
  }

  _handleSaveEditPreferences() {
    this.$.editPrefs.save();
  }

  _handleSaveMenu() {
    this.set('prefs.my', this._localMenu);
    this._cloneMenu(this._localMenu);
    return this.$.restAPI.savePreferences(this.prefs).then(() => {
      this._menuChanged = false;
    });
  }

  _handleResetMenuButton() {
    return this.$.restAPI.getDefaultPreferences().then(data => {
      if (data?.my) {
        this._cloneMenu(data.my);
      }
    });
  }

  _handleSaveWatchedProjects() {
    this.$.watchedProjectsEditor.save();
  }

  _computeHeaderClass(changed?: boolean) {
    return changed ? 'edited' : '';
  }

  _handleSaveEmails() {
    this.$.emailEditor.save();
  }

  _handleNewEmailKeydown(e: CustomKeyboardEvent) {
    if (e.keyCode === 13) {
      // Enter
      e.stopPropagation();
      this._handleAddEmailButton();
    }
  }

  _isNewEmailValid(newEmail?: string): newEmail is string {
    return !!newEmail && newEmail.includes('@');
  }

  _computeAddEmailButtonEnabled(newEmail?: string, addingEmail?: boolean) {
    return this._isNewEmailValid(newEmail) && !addingEmail;
  }

  _handleAddEmailButton() {
    if (!this._isNewEmailValid(this._newEmail)) return;

    this._addingEmail = true;
    this.$.restAPI.addAccountEmail(this._newEmail).then(response => {
      this._addingEmail = false;

      // If it was unsuccessful.
      if (response.status < 200 || response.status >= 300) {
        return;
      }

      this._lastSentVerificationEmail = this._newEmail;
      this._newEmail = '';
    });
  }

  _getFilterDocsLink(docsBaseUrl?: string) {
    let base = docsBaseUrl;
    if (!base || !ABSOLUTE_URL_PATTERN.test(base)) {
      base = GERRIT_DOCS_BASE_URL;
    }

    // Remove any trailing slash, since it is in the GERRIT_DOCS_FILTER_PATH.
    base = base.replace(TRAILING_SLASH_PATTERN, '');

    return base + GERRIT_DOCS_FILTER_PATH;
  }

  _handleToggleDark() {
    if (this._isDark) {
      window.localStorage.removeItem('dark-theme');
      removeDarkTheme();
    } else {
      window.localStorage.setItem('dark-theme', 'true');
      applyDarkTheme();
    }
    this._isDark = !!window.localStorage.getItem('dark-theme');
    fire(
      this,
      EventType.SHOW_ALERT,
      `Theme changed to ${this._isDark ? 'dark' : 'light'}.`
    );
  }

  _showHttpAuth(config?: ServerInfo) {
    if (config && config.auth && config.auth.git_basic_auth_policy) {
      return HTTP_AUTH.includes(
        config.auth.git_basic_auth_policy.toUpperCase()
      );
    }

    return false;
  }

  /**
   * Work around a issue on iOS when clicking turns into double tap
   */
  _onTapDarkToggle(e: Event) {
    e.preventDefault();
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-settings-view': GrSettingsView;
  }
}
