/**
 * @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';

  const NUMBER_FIXED_COLUMNS = 3;
  const CLOSED_STATUS = ['MERGED', 'ABANDONED'];
  const LABEL_PREFIX_INVALID_PROLOG = 'Invalid-Prolog-Rules-Label-Name--';
  const MAX_SHORTCUT_CHARS = 5;

  Polymer({
    is: 'gr-change-list',

    /**
     * Fired when next page key shortcut was pressed.
     *
     * @event next-page
     */

    /**
     * Fired when previous page key shortcut was pressed.
     *
     * @event previous-page
     */

    hostAttributes: {
      tabindex: 0,
    },

    properties: {
      /**
       * The logged-in user's account, or an empty object if no user is logged
       * in.
       */
      account: {
        type: Object,
        value: null,
      },
      /**
       * An array of ChangeInfo objects to render.
       * https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
       */
      changes: {
        type: Array,
        observer: '_changesChanged',
      },
      /**
       * ChangeInfo objects grouped into arrays. The sections and changes
       * properties should not be used together.
       *
       * @type {!Array<{
       *   sectionName: string,
       *   query: string,
       *   results: !Array<!Object>
       * }>}
       */
      sections: {
        type: Array,
        value() { return []; },
      },
      labelNames: {
        type: Array,
        computed: '_computeLabelNames(sections)',
      },
      selectedIndex: {
        type: Number,
        notify: true,
      },
      showNumber: Boolean, // No default value to prevent flickering.
      showStar: {
        type: Boolean,
        value: false,
      },
      showReviewedState: {
        type: Boolean,
        value: false,
      },
      keyEventTarget: {
        type: Object,
        value() { return document.body; },
      },
      changeTableColumns: Array,
      visibleChangeTableColumns: Array,
      preferences: Object,
    },

    behaviors: [
      Gerrit.BaseUrlBehavior,
      Gerrit.ChangeTableBehavior,
      Gerrit.KeyboardShortcutBehavior,
      Gerrit.RESTClientBehavior,
      Gerrit.URLEncodingBehavior,
    ],

    listeners: {
      keydown: '_scopedKeydownHandler',
    },

    observers: [
      '_sectionsChanged(sections.*)',
      '_computePreferences(account, preferences)',
    ],

    keyboardShortcuts() {
      return {
        [this.Shortcut.CURSOR_NEXT_CHANGE]: '_nextChange',
        [this.Shortcut.CURSOR_PREV_CHANGE]: '_prevChange',
        [this.Shortcut.NEXT_PAGE]: '_nextPage',
        [this.Shortcut.PREV_PAGE]: '_prevPage',
        [this.Shortcut.OPEN_CHANGE]: '_openChange',
        [this.Shortcut.TOGGLE_CHANGE_REVIEWED]: '_toggleChangeReviewed',
        [this.Shortcut.TOGGLE_CHANGE_STAR]: '_toggleChangeStar',
        [this.Shortcut.REFRESH_CHANGE_LIST]: '_refreshChangeList',
      };
    },

    /**
     * Iron-a11y-keys-behavior catches keyboard events globally. Some keyboard
     * events must be scoped to a component level (e.g. `enter`) in order to not
     * override native browser functionality.
     *
     * Context: Issue 7294
     */
    _scopedKeydownHandler(e) {
      if (e.keyCode === 13) {
        // Enter.
        this._openChange(e);
      }
    },

    _lowerCase(column) {
      return column.toLowerCase();
    },

    _computePreferences(account, preferences) {
      this.changeTableColumns = this.columnNames;

      if (account) {
        this.showNumber = !!(preferences &&
            preferences.legacycid_in_change_table);
        this.visibleChangeTableColumns = preferences.change_table.length > 0 ?
            this.getVisibleColumns(preferences.change_table) : this.columnNames;
      } else {
        // Not logged in.
        this.showNumber = false;
        this.visibleChangeTableColumns = this.columnNames;
      }
    },

    _computeColspan(changeTableColumns, labelNames) {
      return changeTableColumns.length + labelNames.length +
          NUMBER_FIXED_COLUMNS;
    },

    _computeLabelNames(sections) {
      if (!sections) { return []; }
      let labels = [];
      const nonExistingLabel = function(item) {
        return !labels.includes(item);
      };
      for (const section of sections) {
        if (!section.results) { continue; }
        for (const change of section.results) {
          if (!change.labels) { continue; }
          const currentLabels = Object.keys(change.labels);
          labels = labels.concat(currentLabels.filter(nonExistingLabel));
        }
      }
      return labels.sort();
    },

    _computeLabelShortcut(labelName) {
      if (labelName.startsWith(LABEL_PREFIX_INVALID_PROLOG)) {
        labelName = labelName.slice(LABEL_PREFIX_INVALID_PROLOG.length);
      }
      return labelName.split('-')
          .reduce((a, i) => {
            if (!i) { return a; }
            return a + i[0].toUpperCase();
          }, '')
          .slice(0, MAX_SHORTCUT_CHARS);
    },

    _changesChanged(changes) {
      this.sections = changes ? [{results: changes}] : [];
    },

    _sectionHref(query) {
      return Gerrit.Nav.getUrlForSearchQuery(query);
    },

    /**
     * Maps an index local to a particular section to the absolute index
     * across all the changes on the page.
     *
     * @param {number} sectionIndex index of section
     * @param {number} localIndex index of row within section
     * @return {number} absolute index of row in the aggregate dashboard
     */
    _computeItemAbsoluteIndex(sectionIndex, localIndex) {
      let idx = 0;
      for (let i = 0; i < sectionIndex; i++) {
        idx += this.sections[i].results.length;
      }
      return idx + localIndex;
    },

    _computeItemSelected(sectionIndex, index, selectedIndex) {
      const idx = this._computeItemAbsoluteIndex(sectionIndex, index);
      return idx == selectedIndex;
    },

    _computeItemNeedsReview(account, change, showReviewedState) {
      return showReviewedState && !change.reviewed &&
          !change.work_in_progress &&
          this.changeIsOpen(change.status) &&
          (!account || account._account_id != change.owner._account_id);
    },

    _computeItemHighlight(account, change) {
      // Do not show the assignee highlight if the change is not open.
      if (!change.assignee ||
          !account ||
          CLOSED_STATUS.indexOf(change.status) !== -1) {
        return false;
      }
      return account._account_id === change.assignee._account_id;
    },

    _nextChange(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

      e.preventDefault();
      this.$.cursor.next();
    },

    _prevChange(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

      e.preventDefault();
      this.$.cursor.previous();
    },

    _openChange(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

      e.preventDefault();
      Gerrit.Nav.navigateToChange(this._changeForIndex(this.selectedIndex));
    },

    _nextPage(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e) && !this.isModifierPressed(e, 'shiftKey')) {
        return;
      }

      e.preventDefault();
      this.fire('next-page');
    },

    _prevPage(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e) && !this.isModifierPressed(e, 'shiftKey')) {
        return;
      }

      e.preventDefault();
      this.fire('previous-page');
    },

    _toggleChangeReviewed(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

      e.preventDefault();
      this._toggleReviewedForIndex(this.selectedIndex);
    },

    _toggleReviewedForIndex(index) {
      const changeEls = this._getListItems();
      if (index >= changeEls.length || !changeEls[index]) {
        return;
      }

      const changeEl = changeEls[index];
      changeEl.toggleReviewed();
    },

    _refreshChangeList(e) {
      if (this.shouldSuppressKeyboardShortcut(e)) { return; }

      e.preventDefault();
      this._reloadWindow();
    },

    _reloadWindow() {
      window.location.reload();
    },

    _toggleChangeStar(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

      e.preventDefault();
      this._toggleStarForIndex(this.selectedIndex);
    },

    _toggleStarForIndex(index) {
      const changeEls = this._getListItems();
      if (index >= changeEls.length || !changeEls[index]) {
        return;
      }

      const changeEl = changeEls[index];
      changeEl.$$('gr-change-star').toggleStar();
    },

    _changeForIndex(index) {
      const changeEls = this._getListItems();
      if (index < changeEls.length && changeEls[index]) {
        return changeEls[index].change;
      }
      return null;
    },

    _getListItems() {
      return Polymer.dom(this.root).querySelectorAll('gr-change-list-item');
    },

    _sectionsChanged() {
      // Flush DOM operations so that the list item elements will be loaded.
      Polymer.dom.flush();
      this.$.cursor.stops = this._getListItems();
      this.$.cursor.moveToStart();
    },

    _isOutgoing(section) {
      return !!section.isOutgoing;
    },

    _isEmpty(section) {
      return !section.results.length;
    },
  });
})();
