/**
 * @license
 * Copyright (C) 2015 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/gr-change-list-styles.js';
import '../../shared/gr-account-link/gr-account-link.js';
import '../../shared/gr-change-star/gr-change-star.js';
import '../../shared/gr-change-status/gr-change-status.js';
import '../../shared/gr-date-formatter/gr-date-formatter.js';
import '../../shared/gr-icons/gr-icons.js';
import '../../shared/gr-limited-text/gr-limited-text.js';
import '../../shared/gr-tooltip-content/gr-tooltip-content.js';
import '../../../styles/shared-styles.js';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js';
import '../../plugins/gr-endpoint-param/gr-endpoint-param.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-change-list-item_html.js';
import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
import {ChangeTableBehavior} from '../../../behaviors/gr-change-table-behavior/gr-change-table-behavior.js';
import {PathListBehavior} from '../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.js';
import {URLEncodingBehavior} from '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import {RESTClientBehavior} from '../../../behaviors/rest-client-behavior/rest-client-behavior.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {GrDisplayNameUtils} from '../../../scripts/gr-display-name-utils/gr-display-name-utils.js';
import {pluginEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';

const CHANGE_SIZE = {
  XS: 10,
  SMALL: 50,
  MEDIUM: 250,
  LARGE: 1000,
};

// How many reviewers should be shown with an account-label?
const PRIMARY_REVIEWERS_COUNT = 2;

/**
 * @appliesMixin RESTClientMixin
 * @extends PolymerElement
 */
class GrChangeListItem extends mixinBehaviors( [
  BaseUrlBehavior,
  ChangeTableBehavior,
  PathListBehavior,
  RESTClientBehavior,
  URLEncodingBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-change-list-item'; }

  static get properties() {
    return {
      visibleChangeTableColumns: Array,
      labelNames: {
        type: Array,
      },

      /** @type {?} */
      change: Object,
      config: Object,
      changeURL: {
        type: String,
        computed: '_computeChangeURL(change)',
      },
      statuses: {
        type: Array,
        computed: 'changeStatuses(change)',
      },
      showStar: {
        type: Boolean,
        value: false,
      },
      showNumber: Boolean,
      _changeSize: {
        type: String,
        computed: '_computeChangeSize(change)',
      },
      _dynamicCellEndpoints: {
        type: Array,
      },
    };
  }

  /** @override */
  attached() {
    super.attached();
    pluginLoader.awaitPluginsLoaded().then(() => {
      this._dynamicCellEndpoints = pluginEndpoints.getDynamicEndpoints(
          'change-list-item-cell');
    });
  }

  _computeChangeURL(change) {
    return GerritNav.getUrlForChange(change);
  }

  _computeLabelTitle(change, labelName) {
    const label = change.labels[labelName];
    if (!label) { return 'Label not applicable'; }
    const significantLabel = label.rejected || label.approved ||
        label.disliked || label.recommended;
    if (significantLabel && significantLabel.name) {
      return labelName + '\nby ' + significantLabel.name;
    }
    return labelName;
  }

  _computeLabelClass(change, labelName) {
    const label = change.labels[labelName];
    // Mimic a Set.
    const classes = {
      cell: true,
      label: true,
    };
    if (label) {
      if (label.approved) {
        classes['u-green'] = true;
      }
      if (label.value == 1) {
        classes['u-monospace'] = true;
        classes['u-green'] = true;
      } else if (label.value == -1) {
        classes['u-monospace'] = true;
        classes['u-red'] = true;
      }
      if (label.rejected) {
        classes['u-red'] = true;
      }
    } else {
      classes['u-gray-background'] = true;
    }
    return Object.keys(classes).sort()
        .join(' ');
  }

  _computeLabelValue(change, labelName) {
    const label = change.labels[labelName];
    if (!label) { return ''; }
    if (label.approved) {
      return '✓';
    }
    if (label.rejected) {
      return '✕';
    }
    if (label.value > 0) {
      return '+' + label.value;
    }
    if (label.value < 0) {
      return label.value;
    }
    return '';
  }

  _computeRepoUrl(change) {
    return GerritNav.getUrlForProjectChanges(change.project, true,
        change.internalHost);
  }

  _computeRepoBranchURL(change) {
    return GerritNav.getUrlForBranch(change.branch, change.project, null,
        change.internalHost);
  }

  _computeTopicURL(change) {
    if (!change.topic) { return ''; }
    return GerritNav.getUrlForTopic(change.topic, change.internalHost);
  }

  /**
   * Computes the display string for the project column. If there is a host
   * specified in the change detail, the string will be prefixed with it.
   *
   * @param {!Object} change
   * @param {string=} truncate whether or not the project name should be
   *     truncated. If this value is truthy, the name will be truncated.
   * @return {string}
   */
  _computeRepoDisplay(change, truncate) {
    if (!change || !change.project) { return ''; }
    let str = '';
    if (change.internalHost) { str += change.internalHost + '/'; }
    str += truncate ? this.truncatePath(change.project, 2) : change.project;
    return str;
  }

  _computeSizeTooltip(change) {
    if (change.insertions + change.deletions === 0 ||
        isNaN(change.insertions + change.deletions)) {
      return 'Size unknown';
    } else {
      return `+${change.insertions}, -${change.deletions}`;
    }
  }

  _hasAttention(account) {
    if (!this.change || !this.change.attention_set) return false;
    return this.change.attention_set.hasOwnProperty(account._account_id);
  }

  /**
   * Computes the array of all reviewers with sorting the reviewers first
   * that are in the attention set.
   */
  _computeReviewers(change) {
    if (!change || !change.reviewers || !change.reviewers.REVIEWER) return [];
    const reviewers = [...change.reviewers.REVIEWER];
    reviewers.sort((r1, r2) => {
      if (this._hasAttention(r1)) return -1;
      if (this._hasAttention(r2)) return 1;
      return 0;
    });
    return reviewers;
  }

  _computePrimaryReviewers(change) {
    return this._computeReviewers(change).slice(0, PRIMARY_REVIEWERS_COUNT);
  }

  _computeAdditionalReviewers(change) {
    return this._computeReviewers(change).slice(PRIMARY_REVIEWERS_COUNT);
  }

  _computeAdditionalReviewersCount(change) {
    return this._computeAdditionalReviewers(change).length;
  }

  _computeAdditionalReviewersTitle(change, config) {
    if (!change || !config) return '';
    return this._computeAdditionalReviewers(change)
        .map(user => GrDisplayNameUtils.getDisplayName(config, user))
        .join(', ');
  }

  _computeComments(unresolved_comment_count) {
    if (!unresolved_comment_count || unresolved_comment_count < 1) return '';
    return `${unresolved_comment_count} unresolved`;
  }

  /**
   * TShirt sizing is based on the following paper:
   * http://dirkriehle.com/wp-content/uploads/2008/09/hicss-42-csdistr-final-web.pdf
   */
  _computeChangeSize(change) {
    const delta = change.insertions + change.deletions;
    if (isNaN(delta) || delta === 0) {
      return null; // Unknown
    }
    if (delta < CHANGE_SIZE.XS) {
      return 'XS';
    } else if (delta < CHANGE_SIZE.SMALL) {
      return 'S';
    } else if (delta < CHANGE_SIZE.MEDIUM) {
      return 'M';
    } else if (delta < CHANGE_SIZE.LARGE) {
      return 'L';
    } else {
      return 'XL';
    }
  }

  toggleReviewed() {
    const newVal = !this.change.reviewed;
    this.set('change.reviewed', newVal);
    this.dispatchEvent(new CustomEvent('toggle-reviewed', {
      bubbles: true,
      composed: true,
      detail: {change: this.change, reviewed: newVal},
    }));
  }
}

customElements.define(GrChangeListItem.is, GrChangeListItem);
