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

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

    /**
     * Fired when the "Add reviewer..." button is tapped.
     *
     * @event show-reply-dialog
     */

    properties: {
      change: Object,
      disabled: {
        type: Boolean,
        value: false,
        reflectToAttribute: true,
      },
      mutable: {
        type: Boolean,
        value: false,
      },
      reviewersOnly: {
        type: Boolean,
        value: false,
      },
      ccsOnly: {
        type: Boolean,
        value: false,
      },
      maxReviewersDisplayed: Number,

      _displayedReviewers: {
        type: Array,
        value() { return []; },
      },
      _reviewers: {
        type: Array,
        value() { return []; },
      },
      _showInput: {
        type: Boolean,
        value: false,
      },
      _addLabel: {
        type: String,
        computed: '_computeAddLabel(ccsOnly)',
      },
      _hiddenReviewerCount: {
        type: Number,
        computed: '_computeHiddenCount(_reviewers, _displayedReviewers)',
      },


      // Used for testing.
      _lastAutocompleteRequest: Object,
      _xhrPromise: Object,
    },

    behaviors: [
      Gerrit.FireBehavior,
    ],

    observers: [
      '_reviewersChanged(change.reviewers.*, change.owner)',
    ],

    /**
     * Converts change.permitted_labels to an array of hashes of label keys to
     * numeric scores.
     * Example:
     * [{
     *   'Code-Review': ['-1', ' 0', '+1']
     * }]
     * will be converted to
     * [{
     *   label: 'Code-Review',
     *   scores: [-1, 0, 1]
     * }]
     */
    _permittedLabelsToNumericScores(labels) {
      if (!labels) return [];
      return Object.keys(labels).map(label => ({
        label,
        scores: labels[label].map(v => parseInt(v, 10)),
      }));
    },

    /**
     * Returns hash of labels to max permitted score.
     * @param {!Object} change
     * @returns {!Object} labels to max permitted scores hash
     */
    _getMaxPermittedScores(change) {
      return this._permittedLabelsToNumericScores(change.permitted_labels)
          .map(({label, scores}) => ({
            [label]: scores
                .map(v => parseInt(v, 10))
                .reduce((a, b) => Math.max(a, b))}))
          .reduce((acc, i) => Object.assign(acc, i), {});
    },

    /**
     * Returns max permitted score for reviewer.
     * @param {!Object} reviewer
     * @param {!Object} change
     * @param {string} label
     * @return {number}
     */
    _getReviewerPermittedScore(reviewer, change, label) {
      // Note (issue 7874): sometimes the "all" list is not included in change
      // detail responses, even when DETAILED_LABELS is included in options.
      if (!change.labels[label].all) { return NaN; }
      const detailed = change.labels[label].all.filter(
          ({_account_id}) => reviewer._account_id === _account_id).pop();
      if (!detailed) {
        return NaN;
      }
      if (detailed.hasOwnProperty('permitted_voting_range')) {
        return detailed.permitted_voting_range.max;
      } else if (detailed.hasOwnProperty('value')) {
        // If preset, user can vote on the label.
        return 0;
      }
      return NaN;
    },

    _computeReviewerTooltip(reviewer, change) {
      if (!change || !change.labels) { return ''; }
      const maxScores = [];
      const maxPermitted = this._getMaxPermittedScores(change);
      for (const label of Object.keys(change.labels)) {
        const maxScore =
              this._getReviewerPermittedScore(reviewer, change, label);
        if (isNaN(maxScore) || maxScore < 0) { continue; }
        if (maxScore > 0 && maxScore === maxPermitted[label]) {
          maxScores.push(`${label}: +${maxScore}`);
        } else {
          maxScores.push(`${label}`);
        }
      }
      if (maxScores.length) {
        return 'Votable: ' + maxScores.join(', ');
      } else {
        return '';
      }
    },

    _reviewersChanged(changeRecord, owner) {
      // Polymer 2: check for undefined
      if ([changeRecord, owner].some(arg => arg === undefined)) {
        return;
      }

      let result = [];
      const reviewers = changeRecord.base;
      for (const key in reviewers) {
        if (this.reviewersOnly && key !== 'REVIEWER') {
          continue;
        }
        if (this.ccsOnly && key !== 'CC') {
          continue;
        }
        if (key === 'REVIEWER' || key === 'CC') {
          result = result.concat(reviewers[key]);
        }
      }
      this._reviewers = result.filter(reviewer => {
        return reviewer._account_id != owner._account_id;
      });

      // If there is one more than the max reviewers, don't show the 'show
      // more' button, because it takes up just as much space.
      if (this.maxReviewersDisplayed &&
          this._reviewers.length > this.maxReviewersDisplayed + 1) {
        this._displayedReviewers =
          this._reviewers.slice(0, this.maxReviewersDisplayed);
      } else {
        this._displayedReviewers = this._reviewers;
      }
    },

    _computeHiddenCount(reviewers, displayedReviewers) {
      // Polymer 2: check for undefined
      if ([reviewers, displayedReviewers].some(arg => arg === undefined)) {
        return undefined;
      }

      return reviewers.length - displayedReviewers.length;
    },

    _computeCanRemoveReviewer(reviewer, mutable) {
      if (!mutable) { return false; }

      let current;
      for (let i = 0; i < this.change.removable_reviewers.length; i++) {
        current = this.change.removable_reviewers[i];
        if (current._account_id === reviewer._account_id ||
            (!reviewer._account_id && current.email === reviewer.email)) {
          return true;
        }
      }
      return false;
    },

    _handleRemove(e) {
      e.preventDefault();
      const target = Polymer.dom(e).rootTarget;
      if (!target.account) { return; }
      const accountID = target.account._account_id || target.account.email;
      this.disabled = true;
      this._xhrPromise = this._removeReviewer(accountID).then(response => {
        this.disabled = false;
        if (!response.ok) { return response; }

        const reviewers = this.change.reviewers;

        for (const type of ['REVIEWER', 'CC']) {
          reviewers[type] = reviewers[type] || [];
          for (let i = 0; i < reviewers[type].length; i++) {
            if (reviewers[type][i]._account_id == accountID ||
            reviewers[type][i].email == accountID) {
              this.splice('change.reviewers.' + type, i, 1);
              break;
            }
          }
        }
      }).catch(err => {
        this.disabled = false;
        throw err;
      });
    },

    _handleAddTap(e) {
      e.preventDefault();
      const value = {};
      if (this.reviewersOnly) {
        value.reviewersOnly = true;
      }
      if (this.ccsOnly) {
        value.ccsOnly = true;
      }
      this.fire('show-reply-dialog', {value});
    },

    _handleViewAll(e) {
      this._displayedReviewers = this._reviewers;
    },

    _removeReviewer(id) {
      return this.$.restAPI.removeChangeReviewer(this.change._number, id);
    },

    _computeAddLabel(ccsOnly) {
      return ccsOnly ? 'Add CC' : 'Add reviewer';
    },
  });
})();
