/**
 * @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.
 */
(function() {
  'use strict';

  // Eagerly render Polymer components when backgrounded. (Skips
  // requestAnimationFrame.)
  // @see https://github.com/Polymer/polymer/issues/3851
  // TODO: Reassess after Polymer 2.0 upgrade.
  // @see Issue 4699
  Polymer.RenderStatus._makeReady();

  Polymer({
    is: 'gr-app',

    /**
     * Fired when the URL location changes.
     *
     * @event location-change
     */

    properties: {
      /**
       * @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,
      _isShadowDom: Boolean,
      _pluginScreenName: {
        type: String,
        computed: '_computePluginScreenName(params)',
      },
      _settingsUrl: String,
      _feedbackUrl: {
        type: String,
        value: 'https://bugs.chromium.org/p/gerrit/issues/entry' +
          '?template=PolyGerrit%20Issue',
      },
    },

    listeners: {
      'page-error': '_handlePageError',
      'title-change': '_handleTitleChange',
      'location-change': '_handleLocationChange',
      'rpc-log': '_handleRpcLog',
    },

    observers: [
      '_viewChanged(params.view)',
      '_paramsChanged(params.*)',
    ],

    behaviors: [
      Gerrit.BaseUrlBehavior,
      Gerrit.KeyboardShortcutBehavior,
    ],

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

    created() {
      this._bindKeyboardShortcuts();
    },

    ready() {
      this._isShadowDom = Polymer.Settings.useShadow;
      this.$.router.start();

      this.$.restAPI.getAccount().then(account => {
        this._account = account;
      });
      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')) {
        this.$.libLoader.getDarkTheme().then(module => {
          Polymer.dom(this.root).appendChild(module);
        });
      }

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

      this.$.reporting.appStarted(document.visibilityState === 'hidden');

      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.OPEN_SHORTCUT_HELP_DIALOG, '?');
      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.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');
      this.bindShortcut(
          this.Shortcut.TOGGLE_CHANGE_STAR, 's');
      this.bindShortcut(
          this.Shortcut.REFRESH_CHANGE_LIST, 'shift+r');
      this.bindShortcut(
          this.Shortcut.EDIT_TOPIC, 't');

      this.bindShortcut(
          this.Shortcut.OPEN_REPLY_DIALOG, 'a');
      this.bindShortcut(
          this.Shortcut.OPEN_DOWNLOAD_DIALOG, 'd');
      this.bindShortcut(
          this.Shortcut.EXPAND_ALL_MESSAGES, 'x');
      this.bindShortcut(
          this.Shortcut.COLLAPSE_ALL_MESSAGES, 'z');
      this.bindShortcut(
          this.Shortcut.REFRESH_CHANGE, 'shift+r');
      this.bindShortcut(
          this.Shortcut.UP_TO_DASHBOARD, 'u');
      this.bindShortcut(
          this.Shortcut.UP_TO_CHANGE, 'u');
      this.bindShortcut(
          this.Shortcut.TOGGLE_DIFF_MODE, 'm');

      this.bindShortcut(
          this.Shortcut.NEXT_LINE, 'j', 'down');
      this.bindShortcut(
          this.Shortcut.PREV_LINE, 'k', 'up');
      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');

      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');
      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.OPEN_FIRST_FILE, ']');
      this.bindShortcut(
          this.Shortcut.OPEN_LAST_FILE, '[');

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

    _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 === Gerrit.Nav.View.SEARCH);
      this.set('_showDashboardView', view === Gerrit.Nav.View.DASHBOARD);
      this.set('_showChangeView', view === Gerrit.Nav.View.CHANGE);
      this.set('_showDiffView', view === Gerrit.Nav.View.DIFF);
      this.set('_showSettingsView', view === Gerrit.Nav.View.SETTINGS);
      this.set('_showAdminView', view === Gerrit.Nav.View.ADMIN ||
          view === Gerrit.Nav.View.GROUP || view === Gerrit.Nav.View.REPO);
      this.set('_showCLAView', view === Gerrit.Nav.View.AGREEMENTS);
      this.set('_showEditorView', view === Gerrit.Nav.View.EDIT);
      const isPluginScreen = view === Gerrit.Nav.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 === Gerrit.Nav.View.DOCUMENTATION_SEARCH);
      if (this.params.justRegistered) {
        this.$.registrationOverlay.open();
        this.$.registrationDialog.loadData().then(() => {
          this.$.registrationOverlay.refit();
        });
      }
      this.$.header.unfloat();
    },

    _computeShowGwtUiLink(config) {
      return !window.DEPRECATE_GWT_UI &&
          config.gerrit.web_uis && config.gerrit.web_uis.includes('GWT');
    },

    _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) {
      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);
    },

    _paramsChanged(paramsRecord) {
      const params = paramsRecord.base;
      const viewsToCheck = [Gerrit.Nav.View.SEARCH, Gerrit.Nav.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 = '';
      }
    },

    _showKeyboardShortcuts(e) {
      if (this.shouldSuppressKeyboardShortcut(e)) { return; }
      this.$.keyboardShortcuts.open();
    },

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

    _handleAccountDetailUpdate(e) {
      this.$.mainHeader.reload();
      if (this.params.view === Gerrit.Nav.View.SETTINGS) {
        this.$$('gr-settings-view').reloadAccountDetail();
      }
    },

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

    _computeShadowClass(isShadowDom) {
      return isShadowDom ? 'shadow' : '';
    },

    _goToOpenedChanges() {
      Gerrit.Nav.navigateToStatusSearch('open');
    },

    _goToMergedChanges() {
      Gerrit.Nav.navigateToStatusSearch('merged');
    },

    _goToAbandonedChanges() {
      Gerrit.Nav.navigateToStatusSearch('abandoned');
    },

    _computePluginScreenName({plugin, screen}) {
      return Gerrit._getPluginScreenName(plugin, 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}`);
      }
      const renderTime = new Date(window.performance.timing.loadEventStart);
      console.log(`Document loaded at: ${renderTime}`);
      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);
    },
  });
})();
