/**
 * @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 PATCH_SET_PREFIX_PATTERN = /^Patch Set \d+: /;
  const LABEL_TITLE_SCORE_PATTERN = /^([A-Za-z0-9-]+)([+-]\d+)$/;

  /**
    * @appliesMixin Gerrit.FireMixin
    */
  class GrMessage extends Polymer.mixinBehaviors( [
    Gerrit.FireBehavior,
  ], Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element))) {
    static get is() { return 'gr-message'; }
    /**
     * Fired when this message's reply link is tapped.
     *
     * @event reply
     */

    /**
     * Fired when the message's timestamp is tapped.
     *
     * @event message-anchor-tap
     */

    static get properties() {
      return {
        changeNum: Number,
        /** @type {?} */
        message: Object,
        author: {
          type: Object,
          computed: '_computeAuthor(message)',
        },
        comments: {
          type: Object,
          observer: '_commentsChanged',
        },
        config: Object,
        hideAutomated: {
          type: Boolean,
          value: false,
        },
        hidden: {
          type: Boolean,
          computed: '_computeIsHidden(hideAutomated, isAutomated)',
          reflectToAttribute: true,
        },
        isAutomated: {
          type: Boolean,
          computed: '_computeIsAutomated(message)',
        },
        showAvatar: {
          type: Boolean,
          computed: '_computeShowAvatar(author, config)',
        },
        showOnBehalfOf: {
          type: Boolean,
          computed: '_computeShowOnBehalfOf(message)',
        },
        showReplyButton: {
          type: Boolean,
          computed: '_computeShowReplyButton(message, _loggedIn)',
        },
        projectName: {
          type: String,
          observer: '_projectNameChanged',
        },

        /**
       * A mapping from label names to objects representing the minimum and
       * maximum possible values for that label.
       */
        labelExtremes: Object,

        /**
       * @type {{ commentlinks: Array }}
       */
        _projectConfig: Object,
        // Computed property needed to trigger Polymer value observing.
        _expanded: {
          type: Object,
          computed: '_computeExpanded(message.expanded)',
        },
        _loggedIn: {
          type: Boolean,
          value: false,
        },
      };
    }

    static get observers() {
      return [
        '_updateExpandedClass(message.expanded)',
      ];
    }

    created() {
      super.created();
      this.addEventListener('click',
          e => this._handleClick(e));
    }

    ready() {
      super.ready();
      this.$.restAPI.getConfig().then(config => {
        this.config = config;
      });
      this.$.restAPI.getLoggedIn().then(loggedIn => {
        this._loggedIn = loggedIn;
      });
    }

    _updateExpandedClass(expanded) {
      if (expanded) {
        this.classList.add('expanded');
      } else {
        this.classList.remove('expanded');
      }
    }

    _computeAuthor(message) {
      return message.author || message.updated_by;
    }

    _computeShowAvatar(author, config) {
      return !!(author && config && config.plugin && config.plugin.has_avatars);
    }

    _computeShowOnBehalfOf(message) {
      const author = message.author || message.updated_by;
      return !!(author && message.real_author &&
          author._account_id != message.real_author._account_id);
    }

    _computeShowReplyButton(message, loggedIn) {
      return message && !!message.message && loggedIn &&
          !this._computeIsAutomated(message);
    }

    _computeExpanded(expanded) {
      return expanded;
    }

    /**
     * If there is no value set on the message object as to whether _expanded
     * should be true or not, then _expanded is set to true if there are
     * inline comments (otherwise false).
     */
    _commentsChanged(value) {
      if (this.message && this.message.expanded === undefined) {
        this.set('message.expanded', Object.keys(value || {}).length > 0);
      }
    }

    _handleClick(e) {
      if (this.message.expanded) { return; }
      e.stopPropagation();
      this.set('message.expanded', true);
    }

    _handleAuthorClick(e) {
      if (!this.message.expanded) { return; }
      e.stopPropagation();
      this.set('message.expanded', false);
    }

    _computeIsAutomated(message) {
      return !!(message.reviewer ||
          this._computeIsReviewerUpdate(message) ||
          (message.tag && message.tag.startsWith('autogenerated')));
    }

    _computeIsHidden(hideAutomated, isAutomated) {
      return hideAutomated && isAutomated;
    }

    _computeIsReviewerUpdate(event) {
      return event.type === 'REVIEWER_UPDATE';
    }

    _getScores(message) {
      if (!message.message) { return []; }
      const line = message.message.split('\n', 1)[0];
      const patchSetPrefix = PATCH_SET_PREFIX_PATTERN;
      if (!line.match(patchSetPrefix)) { return []; }
      const scoresRaw = line.split(patchSetPrefix)[1];
      if (!scoresRaw) { return []; }
      return scoresRaw.split(' ')
          .map(s => s.match(LABEL_TITLE_SCORE_PATTERN))
          .filter(ms => ms && ms.length === 3)
          .map(ms => ({label: ms[1], value: ms[2]}));
    }

    _computeScoreClass(score, labelExtremes) {
      // Polymer 2: check for undefined
      if ([score, labelExtremes].some(arg => arg === undefined)) {
        return '';
      }
      const classes = [];
      if (score.value > 0) {
        classes.push('positive');
      } else if (score.value < 0) {
        classes.push('negative');
      }
      const extremes = labelExtremes[score.label];
      if (extremes) {
        const intScore = parseInt(score.value, 10);
        if (intScore === extremes.max) {
          classes.push('max');
        } else if (intScore === extremes.min) {
          classes.push('min');
        }
      }
      return classes.join(' ');
    }

    _computeClass(expanded, showAvatar, message) {
      const classes = [];
      classes.push(expanded ? 'expanded' : 'collapsed');
      classes.push(showAvatar ? 'showAvatar' : 'hideAvatar');
      return classes.join(' ');
    }

    _handleAnchorClick(e) {
      e.preventDefault();
      this.dispatchEvent(new CustomEvent('message-anchor-tap', {
        bubbles: true,
        composed: true,
        detail: {id: this.message.id},
      }));
    }

    _handleReplyTap(e) {
      e.preventDefault();
      this.fire('reply', {message: this.message});
    }

    _projectNameChanged(name) {
      this.$.restAPI.getProjectConfig(name).then(config => {
        this._projectConfig = config;
      });
    }

    _computeExpandToggleIcon(expanded) {
      return expanded ? 'gr-icons:expand-less' : 'gr-icons:expand-more';
    }

    _toggleExpanded(e) {
      e.stopPropagation();
      this.set('message.expanded', !this.message.expanded);
    }
  }

  customElements.define(GrMessage.is, GrMessage);
})();
