/**
 * @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+)$/;

  Polymer({
    is: 'gr-message',
    _legacyUndefinedCheck: true,

    /**
     * Fired when this message's reply link is tapped.
     *
     * @event reply
     */

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

    listeners: {
      tap: '_handleTap',
    },

    properties: {
      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,
      },
    },

    behaviors: [
      Gerrit.FireBehavior,
    ],

    observers: [
      '_updateExpandedClass(message.expanded)',
    ],

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

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

    _handleAuthorTap(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) {
      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(' ');
    },

    _handleAnchorTap(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);
    },
  });
})();
