/**
 * @license
 * Copyright (C) 2019 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 '../styles/shared-styles.js';
import '../styles/themes/app-theme.js';
import {applyTheme as applyDarkTheme} from '../styles/themes/dark-theme.js';
import './admin/gr-admin-view/gr-admin-view.js';
import './documentation/gr-documentation-search/gr-documentation-search.js';
import './change-list/gr-change-list-view/gr-change-list-view.js';
import './change-list/gr-dashboard-view/gr-dashboard-view.js';
import './change/gr-change-view/gr-change-view.js';
import './core/gr-error-manager/gr-error-manager.js';
import './core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.js';
import './core/gr-main-header/gr-main-header.js';
import './core/gr-router/gr-router.js';
import './core/gr-smart-search/gr-smart-search.js';
import './diff/gr-diff-view/gr-diff-view.js';
import './edit/gr-editor-view/gr-editor-view.js';
import './plugins/gr-endpoint-decorator/gr-endpoint-decorator.js';
import './plugins/gr-endpoint-param/gr-endpoint-param.js';
import './plugins/gr-endpoint-slot/gr-endpoint-slot.js';
import './plugins/gr-external-style/gr-external-style.js';
import './plugins/gr-plugin-host/gr-plugin-host.js';
import './settings/gr-cla-view/gr-cla-view.js';
import './settings/gr-registration-dialog/gr-registration-dialog.js';
import './settings/gr-settings-view/gr-settings-view.js';
import './shared/gr-fixed-panel/gr-fixed-panel.js';
import './shared/gr-lib-loader/gr-lib-loader.js';
import './shared/gr-rest-api-interface/gr-rest-api-interface.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-app-element_html.js';
import {BaseUrlBehavior} from '../behaviors/base-url-behavior/base-url-behavior.js';
import {KeyboardShortcutBehavior} from '../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
import {GerritNav} from './core/gr-navigation/gr-navigation.js';
import {appContext} from '../services/app-context.js';

/**
 * @extends PolymerElement
 */
class GrAppElement extends mixinBehaviors( [
  BaseUrlBehavior,
  KeyboardShortcutBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-app-element'; }
  /**
   * Fired when the URL location changes.
   *
   * @event location-change
   */

  static get properties() {
    return {
    /**
     * @type {{ query: string, view: string, screen: string }}
     */
      params: Object,
      keyEventTarget: {
        type: Object,
        value() { return document.body; },
      },

      _account: {
        type: Object,
        observer: '_accountChanged',
      },

      /**
       * The last time the g key was pressed in milliseconds (or a keydown event
       * was handled if the key is held down).
       *
       * @type {number|null}
       */
      _lastGKeyPressTimestamp: {
        type: Number,
        value: null,
      },

      /**
       * @type {{ plugin: Object }}
       */
      _serverConfig: Object,
      _version: String,
      _showChangeListView: Boolean,
      _showDashboardView: Boolean,
      _showChangeView: Boolean,
      _showDiffView: Boolean,
      _showSettingsView: Boolean,
      _showAdminView: Boolean,
      _showCLAView: Boolean,
      _showEditorView: Boolean,
      _showPluginScreen: Boolean,
      _showDocumentationSearch: Boolean,
      /** @type {?} */
      _viewState: Object,
      /** @type {?} */
      _lastError: Object,
      _lastSearchPage: String,
      _path: String,
      _pluginScreenName: {
        type: String,
        computed: '_computePluginScreenName(params)',
      },
      _settingsUrl: String,
      _feedbackUrl: String,
      // Used to allow searching on mobile
      mobileSearch: {
        type: Boolean,
        value: false,
      },

      /**
       * Other elements in app must open this URL when
       * user login is required.
       */
      _loginUrl: {
        type: String,
        value: '/login',
      },
    };
  }

  static get observers() {
    return [
      '_viewChanged(params.view)',
      '_paramsChanged(params.*)',
    ];
  }

  keyboardShortcuts() {
    return {
      [this.Shortcut.OPEN_SHORTCUT_HELP_DIALOG]: '_showKeyboardShortcuts',
      [this.Shortcut.GO_TO_USER_DASHBOARD]: '_goToUserDashboard',
      [this.Shortcut.GO_TO_OPENED_CHANGES]: '_goToOpenedChanges',
      [this.Shortcut.GO_TO_MERGED_CHANGES]: '_goToMergedChanges',
      [this.Shortcut.GO_TO_ABANDONED_CHANGES]: '_goToAbandonedChanges',
      [this.Shortcut.GO_TO_WATCHED_CHANGES]: '_goToWatchedChanges',
    };
  }

  constructor() {
    super();
    this.reporting = appContext.reportingService;
  }

  /** @override */
  created() {
    super.created();
    this._bindKeyboardShortcuts();
    this.addEventListener('page-error',
        e => this._handlePageError(e));
    this.addEventListener('title-change',
        e => this._handleTitleChange(e));
    this.addEventListener('location-change',
        e => this._handleLocationChange(e));
    this.addEventListener('rpc-log',
        e => this._handleRpcLog(e));
    this.addEventListener('shortcut-triggered',
        e => this._handleShortcutTriggered(e));
  }

  /** @override */
  ready() {
    super.ready();
    this._updateLoginUrl();
    this.reporting.appStarted();
    this.$.router.start();

    this.$.restAPI.getAccount().then(account => {
      this._account = account;
      const role = account ? 'user' : 'guest';
      this.reporting.reportLifeCycle(`Started as ${role}`);
    });
    this.$.restAPI.getConfig().then(config => {
      this._serverConfig = config;

      if (config && config.gerrit && config.gerrit.report_bug_url) {
        this._feedbackUrl = config.gerrit.report_bug_url;
      }
    });
    this.$.restAPI.getVersion().then(version => {
      this._version = version;
      this._logWelcome();
    });

    if (window.localStorage.getItem('dark-theme')) {
      applyDarkTheme();
    }

    // Note: this is evaluated here to ensure that it only happens after the
    // router has been initialized. @see Issue 7837
    this._settingsUrl = GerritNav.getUrlForSettings();

    this._viewState = {
      changeView: {
        changeNum: null,
        patchRange: null,
        selectedFileIndex: 0,
        showReplyDialog: false,
        diffMode: null,
        numFilesShown: null,
        scrollTop: 0,
      },
      changeListView: {
        query: null,
        offset: 0,
        selectedChangeIndex: 0,
      },
      dashboardView: {
        selectedChangeIndex: 0,
      },
    };
  }

  _bindKeyboardShortcuts() {
    this.bindShortcut(this.Shortcut.SEND_REPLY,
        this.DOC_ONLY, 'ctrl+enter', 'meta+enter');
    this.bindShortcut(this.Shortcut.EMOJI_DROPDOWN,
        this.DOC_ONLY, ':');

    this.bindShortcut(
        this.Shortcut.OPEN_SHORTCUT_HELP_DIALOG, '?');
    this.bindShortcut(
        this.Shortcut.GO_TO_USER_DASHBOARD, this.GO_KEY, 'i');
    this.bindShortcut(
        this.Shortcut.GO_TO_OPENED_CHANGES, this.GO_KEY, 'o');
    this.bindShortcut(
        this.Shortcut.GO_TO_MERGED_CHANGES, this.GO_KEY, 'm');
    this.bindShortcut(
        this.Shortcut.GO_TO_ABANDONED_CHANGES, this.GO_KEY, 'a');
    this.bindShortcut(
        this.Shortcut.GO_TO_WATCHED_CHANGES, this.GO_KEY, 'w');

    this.bindShortcut(
        this.Shortcut.CURSOR_NEXT_CHANGE, 'j');
    this.bindShortcut(
        this.Shortcut.CURSOR_PREV_CHANGE, 'k');
    this.bindShortcut(
        this.Shortcut.OPEN_CHANGE, 'o');
    this.bindShortcut(
        this.Shortcut.NEXT_PAGE, 'n', ']');
    this.bindShortcut(
        this.Shortcut.PREV_PAGE, 'p', '[');
    this.bindShortcut(
        this.Shortcut.TOGGLE_CHANGE_REVIEWED, 'r:keyup');
    this.bindShortcut(
        this.Shortcut.TOGGLE_CHANGE_STAR, 's:keyup');
    this.bindShortcut(
        this.Shortcut.REFRESH_CHANGE_LIST, 'shift+r:keyup');
    this.bindShortcut(
        this.Shortcut.EDIT_TOPIC, 't');

    this.bindShortcut(
        this.Shortcut.OPEN_REPLY_DIALOG, 'a:keyup');
    this.bindShortcut(
        this.Shortcut.OPEN_DOWNLOAD_DIALOG, 'd:keyup');
    this.bindShortcut(
        this.Shortcut.EXPAND_ALL_MESSAGES, 'x');
    this.bindShortcut(
        this.Shortcut.COLLAPSE_ALL_MESSAGES, 'z');
    this.bindShortcut(
        this.Shortcut.REFRESH_CHANGE, 'shift+r:keyup');
    this.bindShortcut(
        this.Shortcut.UP_TO_DASHBOARD, 'u');
    this.bindShortcut(
        this.Shortcut.UP_TO_CHANGE, 'u');
    this.bindShortcut(
        this.Shortcut.TOGGLE_DIFF_MODE, 'm:keyup');
    this.bindShortcut(
        this.Shortcut.DIFF_AGAINST_BASE, this.V_KEY, 'down', 's');
    this.bindShortcut(
        this.Shortcut.DIFF_AGAINST_LATEST, this.V_KEY, 'up', 'w');
    this.bindShortcut(
        this.Shortcut.DIFF_BASE_AGAINST_LEFT, this.V_KEY, 'left', 'a');
    this.bindShortcut(
        this.Shortcut.DIFF_RIGHT_AGAINST_LATEST, this.V_KEY, 'right', 'd');
    this.bindShortcut(
        this.Shortcut.DIFF_BASE_AGAINST_LATEST, this.V_KEY, 'b');

    this.bindShortcut(
        this.Shortcut.NEXT_LINE, 'j', 'down');
    this.bindShortcut(
        this.Shortcut.PREV_LINE, 'k', 'up');
    if (this._isCursorManagerSupportMoveToVisibleLine()) {
      this.bindShortcut(
          this.Shortcut.VISIBLE_LINE, '.');
    }
    this.bindShortcut(
        this.Shortcut.NEXT_CHUNK, 'n');
    this.bindShortcut(
        this.Shortcut.PREV_CHUNK, 'p');
    this.bindShortcut(
        this.Shortcut.EXPAND_ALL_DIFF_CONTEXT, 'shift+x');
    this.bindShortcut(
        this.Shortcut.NEXT_COMMENT_THREAD, 'shift+n');
    this.bindShortcut(
        this.Shortcut.PREV_COMMENT_THREAD, 'shift+p');
    this.bindShortcut(
        this.Shortcut.EXPAND_ALL_COMMENT_THREADS, this.DOC_ONLY, 'e');
    this.bindShortcut(
        this.Shortcut.COLLAPSE_ALL_COMMENT_THREADS,
        this.DOC_ONLY, 'shift+e');
    this.bindShortcut(
        this.Shortcut.LEFT_PANE, 'shift+left');
    this.bindShortcut(
        this.Shortcut.RIGHT_PANE, 'shift+right');
    this.bindShortcut(
        this.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
    this.bindShortcut(
        this.Shortcut.NEW_COMMENT, 'c');
    this.bindShortcut(
        this.Shortcut.SAVE_COMMENT,
        'ctrl+enter', 'meta+enter', 'ctrl+s', 'meta+s');
    this.bindShortcut(
        this.Shortcut.OPEN_DIFF_PREFS, ',');
    this.bindShortcut(
        this.Shortcut.TOGGLE_DIFF_REVIEWED, 'r:keyup');

    this.bindShortcut(
        this.Shortcut.NEXT_FILE, ']');
    this.bindShortcut(
        this.Shortcut.PREV_FILE, '[');
    this.bindShortcut(
        this.Shortcut.NEXT_FILE_WITH_COMMENTS, 'shift+j');
    this.bindShortcut(
        this.Shortcut.PREV_FILE_WITH_COMMENTS, 'shift+k');
    this.bindShortcut(
        this.Shortcut.CURSOR_NEXT_FILE, 'j', 'down');
    this.bindShortcut(
        this.Shortcut.CURSOR_PREV_FILE, 'k', 'up');
    this.bindShortcut(
        this.Shortcut.OPEN_FILE, 'o', 'enter');
    this.bindShortcut(
        this.Shortcut.TOGGLE_FILE_REVIEWED, 'r:keyup');
    this.bindShortcut(
        this.Shortcut.NEXT_UNREVIEWED_FILE, 'shift+m');
    this.bindShortcut(
        this.Shortcut.TOGGLE_ALL_INLINE_DIFFS, 'shift+i:keyup');
    this.bindShortcut(
        this.Shortcut.TOGGLE_INLINE_DIFF, 'i:keyup');
    this.bindShortcut(
        this.Shortcut.TOGGLE_BLAME, 'b');
    this.bindShortcut(
        this.Shortcut.TOGGLE_HIDE_ALL_COMMENT_THREADS, 'h');

    this.bindShortcut(
        this.Shortcut.OPEN_FIRST_FILE, ']');
    this.bindShortcut(
        this.Shortcut.OPEN_LAST_FILE, '[');

    this.bindShortcut(
        this.Shortcut.SEARCH, '/');
  }

  _isCursorManagerSupportMoveToVisibleLine() {
    // This method is a copy-paste from the
    // method _isIntersectionObserverSupported of gr-cursor-manager.js
    // It is better share this method with gr-cursor-manager,
    // but doing it require a lot if changes instead of 1-line copied code
    return 'IntersectionObserver' in window;
  }

  _accountChanged(account) {
    if (!account) { return; }

    // Preferences are cached when a user is logged in; warm them.
    this.$.restAPI.getPreferences();
    this.$.restAPI.getDiffPreferences();
    this.$.restAPI.getEditPreferences();
    this.$.errorManager.knownAccountId =
        this._account && this._account._account_id || null;
  }

  _viewChanged(view) {
    this.$.errorView.classList.remove('show');
    this.set('_showChangeListView', view === GerritNav.View.SEARCH);
    this.set('_showDashboardView', view === GerritNav.View.DASHBOARD);
    this.set('_showChangeView', view === GerritNav.View.CHANGE);
    this.set('_showDiffView', view === GerritNav.View.DIFF);
    this.set('_showSettingsView', view === GerritNav.View.SETTINGS);
    this.set('_showAdminView', view === GerritNav.View.ADMIN ||
        view === GerritNav.View.GROUP || view === GerritNav.View.REPO);
    this.set('_showCLAView', view === GerritNav.View.AGREEMENTS);
    this.set('_showEditorView', view === GerritNav.View.EDIT);
    const isPluginScreen = view === GerritNav.View.PLUGIN_SCREEN;
    this.set('_showPluginScreen', false);
    // Navigation within plugin screens does not restamp gr-endpoint-decorator
    // because _showPluginScreen value does not change. To force restamp,
    // change _showPluginScreen value between true and false.
    if (isPluginScreen) {
      this.async(() => this.set('_showPluginScreen', true), 1);
    }
    this.set('_showDocumentationSearch',
        view === GerritNav.View.DOCUMENTATION_SEARCH);
    if (this.params.justRegistered) {
      this.$.registrationOverlay.open();
      this.$.registrationDialog.loadData().then(() => {
        this.$.registrationOverlay.refit();
      });
    }
    this.$.header.unfloat();
  }

  _handleShortcutTriggered(event) {
    const {event: e, goKey} = event.detail;
    // eg: {key: "k:keydown", ..., from: "gr-diff-view"}
    let key = `${e.key}:${e.type}`;
    if (goKey) key = 'g+' + key;
    if (e.shiftKey) key = 'shift+' + key;
    if (e.ctrlKey) key = 'ctrl+' + key;
    if (e.metaKey) key = 'meta+' + key;
    if (e.altKey) key = 'alt+' + key;
    this.reporting.reportInteraction('shortcut-triggered', {
      key,
      from: event.path && event.path[0]
        && event.path[0].nodeName || 'unknown',
    });
  }

  _handlePageError(e) {
    const props = [
      '_showChangeListView',
      '_showDashboardView',
      '_showChangeView',
      '_showDiffView',
      '_showSettingsView',
      '_showAdminView',
    ];
    for (const showProp of props) {
      this.set(showProp, false);
    }

    this.$.errorView.classList.add('show');
    const response = e.detail.response;
    const err = {text: [response.status, response.statusText].join(' ')};
    if (response.status === 404) {
      err.emoji = '¯\\_(ツ)_/¯';
      this._lastError = err;
    } else {
      err.emoji = 'o_O';
      response.text().then(text => {
        err.moreInfo = text;
        this._lastError = err;
      });
    }
  }

  _handleLocationChange(e) {
    this._updateLoginUrl();

    const hash = e.detail.hash.substring(1);
    let pathname = e.detail.pathname;
    if (pathname.startsWith('/c/') && parseInt(hash, 10) > 0) {
      pathname += '@' + hash;
    }
    this.set('_path', pathname);
  }

  _updateLoginUrl() {
    const baseUrl = this.getBaseUrl();
    if (baseUrl) {
      // Strip the canonical path from the path since needing canonical in
      // the path is unneeded and breaks the url.
      this._loginUrl = baseUrl + '/login/' + encodeURIComponent(
          '/' + window.location.pathname.substring(baseUrl.length) +
          window.location.search +
          window.location.hash);
    } else {
      this._loginUrl = '/login/' + encodeURIComponent(
          window.location.pathname +
          window.location.search +
          window.location.hash);
    }
  }

  _paramsChanged(paramsRecord) {
    const params = paramsRecord.base;
    const viewsToCheck = [GerritNav.View.SEARCH, GerritNav.View.DASHBOARD];
    if (viewsToCheck.includes(params.view)) {
      this.set('_lastSearchPage', location.pathname);
    }
  }

  _handleTitleChange(e) {
    if (e.detail.title) {
      document.title = e.detail.title + ' · Gerrit Code Review';
    } else {
      document.title = '';
    }
  }

  handleShowKeyboardShortcuts() {
    this.$.keyboardShortcuts.open();
  }

  _showKeyboardShortcuts(e) {
    // same shortcut should close the dialog if pressed again
    // when dialog is open
    if (this.$.keyboardShortcuts.opened) {
      this.$.keyboardShortcuts.close();
      return;
    }
    if (this.shouldSuppressKeyboardShortcut(e)) { return; }
    this.$.keyboardShortcuts.open();
  }

  _handleKeyboardShortcutDialogClose() {
    this.$.keyboardShortcuts.close();
  }

  _handleAccountDetailUpdate(e) {
    this.$.mainHeader.reload();
    if (this.params.view === GerritNav.View.SETTINGS) {
      this.shadowRoot.querySelector('gr-settings-view').reloadAccountDetail();
    }
  }

  _handleRegistrationDialogClose(e) {
    this.params.justRegistered = false;
    this.$.registrationOverlay.close();
  }

  _goToOpenedChanges() {
    GerritNav.navigateToStatusSearch('open');
  }

  _goToUserDashboard() {
    GerritNav.navigateToUserDashboard();
  }

  _goToMergedChanges() {
    GerritNav.navigateToStatusSearch('merged');
  }

  _goToAbandonedChanges() {
    GerritNav.navigateToStatusSearch('abandoned');
  }

  _goToWatchedChanges() {
    // The query is hardcoded, and doesn't respect custom menu entries
    GerritNav.navigateToSearchQuery('is:watched is:open');
  }

  _computePluginScreenName({plugin, screen}) {
    if (!plugin || !screen) return '';
    return `${plugin}-screen-${screen}`;
  }

  _logWelcome() {
    console.group('Runtime Info');
    console.log('Gerrit UI (PolyGerrit)');
    console.log(`Gerrit Server Version: ${this._version}`);
    if (window.VERSION_INFO) {
      console.log(`UI Version Info: ${window.VERSION_INFO}`);
    }
    if (this._feedbackUrl) {
      console.log(`Please file bugs and feedback at: ${this._feedbackUrl}`);
    }
    console.groupEnd();
  }

  /**
   * Intercept RPC log events emitted by REST API interfaces.
   * Note: the REST API interface cannot use gr-reporting directly because
   * that would create a cyclic dependency.
   */
  _handleRpcLog(e) {
    this.reporting.reportRpcTiming(e.detail.anonymizedUrl,
        e.detail.elapsed);
  }

  _mobileSearchToggle(e) {
    this.mobileSearch = !this.mobileSearch;
  }

  getThemeEndpoint() {
    // For now, we only have dark mode and light mode
    return window.localStorage.getItem('dark-theme') ?
      'app-theme-dark' :
      'app-theme-light';
  }
}

customElements.define(GrAppElement.is, GrAppElement);
