/**
 * @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 HASHTAG_ADD_MESSAGE = 'Add Hashtag';

  const SubmitTypeLabel = {
    FAST_FORWARD_ONLY: 'Fast Forward Only',
    MERGE_IF_NECESSARY: 'Merge if Necessary',
    REBASE_IF_NECESSARY: 'Rebase if Necessary',
    MERGE_ALWAYS: 'Always Merge',
    REBASE_ALWAYS: 'Rebase Always',
    CHERRY_PICK: 'Cherry Pick',
  };

  const NOT_CURRENT_MESSAGE = 'Not current - rebase possible';

  /**
   * @enum {string}
   */
  const CertificateStatus = {
    /**
     * This certificate status is bad.
     */
    BAD: 'BAD',
    /**
     * This certificate status is OK.
     */
    OK: 'OK',
    /**
     * This certificate status is TRUSTED.
     */
    TRUSTED: 'TRUSTED',
  };

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

    /**
     * Fired when the change topic is changed.
     *
     * @event topic-changed
     */

    properties: {
      /** @type {?} */
      change: Object,
      labels: {
        type: Object,
        notify: true,
      },
      account: Object,
      /** @type {?} */
      revision: Object,
      commitInfo: Object,
      _mutable: {
        type: Boolean,
        computed: '_computeIsMutable(account)',
      },
      /** @type {?} */
      serverConfig: Object,
      parentIsCurrent: Boolean,
      _notCurrentMessage: {
        type: String,
        value: NOT_CURRENT_MESSAGE,
        readOnly: true,
      },
      _topicReadOnly: {
        type: Boolean,
        computed: '_computeTopicReadOnly(_mutable, change)',
      },
      _hashtagReadOnly: {
        type: Boolean,
        computed: '_computeHashtagReadOnly(_mutable, change)',
      },
      /**
       * @type {Gerrit.PushCertificateValidation}
       */
      _pushCertificateValidation: {
        type: Object,
        computed: '_computePushCertificateValidation(serverConfig, change)',
      },
      _showRequirements: {
        type: Boolean,
        computed: '_computeShowRequirements(change)',
      },

      _assignee: Array,
      _isWip: {
        type: Boolean,
        computed: '_computeIsWip(change)',
      },
      _newHashtag: String,

      _settingTopic: {
        type: Boolean,
        value: false,
      },

      _currentParents: {
        type: Array,
        computed: '_computeParents(change, revision)',
      },

      /** @type {?} */
      _CHANGE_ROLE: {
        type: Object,
        readOnly: true,
        value: {
          OWNER: 'owner',
          UPLOADER: 'uploader',
          AUTHOR: 'author',
          COMMITTER: 'committer',
        },
      },
    },

    behaviors: [
      Gerrit.RESTClientBehavior,
    ],

    observers: [
      '_changeChanged(change)',
      '_labelsChanged(change.labels)',
      '_assigneeChanged(_assignee.*)',
    ],

    _labelsChanged(labels) {
      this.labels = Object.assign({}, labels) || null;
    },

    _changeChanged(change) {
      this._assignee = change.assignee ? [change.assignee] : [];
    },

    _assigneeChanged(assigneeRecord) {
      if (!this.change) { return; }
      const assignee = assigneeRecord.base;
      if (assignee.length) {
        const acct = assignee[0];
        if (this.change.assignee &&
            acct._account_id === this.change.assignee._account_id) { return; }
        this.set(['change', 'assignee'], acct);
        this.$.restAPI.setAssignee(this.change._number, acct._account_id);
      } else {
        if (!this.change.assignee) { return; }
        this.set(['change', 'assignee'], undefined);
        this.$.restAPI.deleteAssignee(this.change._number);
      }
    },

    _computeHideStrategy(change) {
      return !this.changeIsOpen(change);
    },

    /**
     * @param {Object} commitInfo
     * @return {?Array} If array is empty, returns null instead so
     * an existential check can be used to hide or show the webLinks
     * section.
     */
    _computeWebLinks(commitInfo, serverConfig) {
      if (!commitInfo) { return null; }
      const weblinks = Gerrit.Nav.getChangeWeblinks(
          this.change ? this.change.repo : '',
          commitInfo.commit,
          {
            weblinks: commitInfo.web_links,
            config: serverConfig,
          });
      return weblinks.length ? weblinks : null;
    },

    _computeStrategy(change) {
      return SubmitTypeLabel[change.submit_type];
    },

    _computeLabelNames(labels) {
      return Object.keys(labels).sort();
    },

    _handleTopicChanged(e, topic) {
      const lastTopic = this.change.topic;
      if (!topic.length) { topic = null; }
      this._settingTopic = true;
      this.$.restAPI.setChangeTopic(this.change._number, topic)
          .then(newTopic => {
            this._settingTopic = false;
            this.set(['change', 'topic'], newTopic);
            if (newTopic !== lastTopic) {
              this.dispatchEvent(new CustomEvent(
                  'topic-changed', {bubbles: true, composed: true}));
            }
          });
    },

    _showAddTopic(changeRecord, settingTopic) {
      const hasTopic = !!changeRecord &&
          !!changeRecord.base && !!changeRecord.base.topic;
      return !hasTopic && !settingTopic;
    },

    _showTopicChip(changeRecord, settingTopic) {
      const hasTopic = !!changeRecord &&
          !!changeRecord.base && !!changeRecord.base.topic;
      return hasTopic && !settingTopic;
    },

    _handleHashtagChanged(e) {
      const lastHashtag = this.change.hashtag;
      if (!this._newHashtag.length) { return; }
      const newHashtag = this._newHashtag;
      this._newHashtag = '';
      this.$.restAPI.setChangeHashtag(
          this.change._number, {add: [newHashtag]}).then(newHashtag => {
        this.set(['change', 'hashtags'], newHashtag);
        if (newHashtag !== lastHashtag) {
          this.dispatchEvent(
              new CustomEvent('hashtag-changed', {
                bubbles: true, composed: true}));
        }
      });
    },

    _computeTopicReadOnly(mutable, change) {
      return !mutable ||
          !change ||
          !change.actions ||
          !change.actions.topic ||
          !change.actions.topic.enabled;
    },

    _computeHashtagReadOnly(mutable, change) {
      return !mutable ||
          !change ||
          !change.actions ||
          !change.actions.hashtags ||
          !change.actions.hashtags.enabled;
    },

    _computeAssigneeReadOnly(mutable, change) {
      return !mutable ||
          !change ||
          !change.actions ||
          !change.actions.assignee ||
          !change.actions.assignee.enabled;
    },

    _computeTopicPlaceholder(_topicReadOnly) {
      // Action items in Material Design are uppercase -- placeholder label text
      // is sentence case.
      return _topicReadOnly ? 'No topic' : 'ADD TOPIC';
    },

    _computeHashtagPlaceholder(_hashtagReadOnly) {
      return _hashtagReadOnly ? '' : HASHTAG_ADD_MESSAGE;
    },

    _computeShowRequirements(change) {
      if (change.status !== this.ChangeStatus.NEW) {
        // TODO(maximeg) change this to display the stored
        // requirements, once it is implemented server-side.
        return false;
      }
      const hasRequirements = !!change.requirements &&
          Object.keys(change.requirements).length > 0;
      const hasLabels = !!change.labels &&
          Object.keys(change.labels).length > 0;
      return hasRequirements || hasLabels || !!change.work_in_progress;
    },

    /**
     * @return {?Gerrit.PushCertificateValidation} object representing data for
     *     the push validation.
     */
    _computePushCertificateValidation(serverConfig, change) {
      if (!change || !serverConfig || !serverConfig.receive ||
          !serverConfig.receive.enable_signed_push) {
        return null;
      }
      const rev = change.revisions[change.current_revision];
      if (!rev.push_certificate || !rev.push_certificate.key) {
        return {
          class: 'help',
          icon: 'gr-icons:help',
          message: 'This patch set was created without a push certificate',
        };
      }

      const key = rev.push_certificate.key;
      switch (key.status) {
        case CertificateStatus.BAD:
          return {
            class: 'invalid',
            icon: 'gr-icons:close',
            message: this._problems('Push certificate is invalid', key),
          };
        case CertificateStatus.OK:
          return {
            class: 'notTrusted',
            icon: 'gr-icons:info',
            message: this._problems(
                'Push certificate is valid, but key is not trusted', key),
          };
        case CertificateStatus.TRUSTED:
          return {
            class: 'trusted',
            icon: 'gr-icons:check',
            message: this._problems(
                'Push certificate is valid and key is trusted', key),
          };
        default:
          throw new Error(`unknown certificate status: ${key.status}`);
      }
    },

    _problems(msg, key) {
      if (!key || !key.problems || key.problems.length === 0) {
        return msg;
      }

      return [msg + ':'].concat(key.problems).join('\n');
    },

    _computeProjectURL(project) {
      return Gerrit.Nav.getUrlForProjectChanges(project);
    },

    _computeBranchURL(project, branch) {
      if (!this.change || !this.change.status) return '';
      return Gerrit.Nav.getUrlForBranch(branch, project,
          this.change.status == this.ChangeStatus.NEW ? 'open' :
            this.change.status.toLowerCase());
    },

    _computeTopicURL(topic) {
      return Gerrit.Nav.getUrlForTopic(topic);
    },

    _computeHashtagURL(hashtag) {
      return Gerrit.Nav.getUrlForHashtag(hashtag);
    },

    _handleTopicRemoved(e) {
      const target = Polymer.dom(e).rootTarget;
      target.disabled = true;
      this.$.restAPI.setChangeTopic(this.change._number, null).then(() => {
        target.disabled = false;
        this.set(['change', 'topic'], '');
        this.dispatchEvent(
            new CustomEvent('topic-changed', {bubbles: true, composed: true}));
      }).catch(err => {
        target.disabled = false;
        return;
      });
    },

    _handleHashtagRemoved(e) {
      e.preventDefault();
      const target = Polymer.dom(e).rootTarget;
      target.disabled = true;
      this.$.restAPI.setChangeHashtag(this.change._number,
          {remove: [target.text]})
          .then(newHashtag => {
            target.disabled = false;
            this.set(['change', 'hashtags'], newHashtag);
          }).catch(err => {
            target.disabled = false;
            return;
          });
    },

    _computeIsWip(change) {
      return !!change.work_in_progress;
    },

    _computeShowRoleClass(change, role) {
      return this._getNonOwnerRole(change, role) ? '' : 'hideDisplay';
    },

    /**
     * Get the user with the specified role on the change. Returns null if the
     * user with that role is the same as the owner.
     *
     * @param {!Object} change
     * @param {string} role One of the values from _CHANGE_ROLE
     * @return {Object|null} either an accound or null.
     */
    _getNonOwnerRole(change, role) {
      if (!change || !change.current_revision ||
          !change.revisions[change.current_revision]) {
        return null;
      }

      const rev = change.revisions[change.current_revision];
      if (!rev) { return null; }

      if (role === this._CHANGE_ROLE.UPLOADER &&
          rev.uploader &&
          change.owner._account_id !== rev.uploader._account_id) {
        return rev.uploader;
      }

      if (role === this._CHANGE_ROLE.AUTHOR &&
          rev.commit && rev.commit.author &&
          change.owner.email !== rev.commit.author.email) {
        return rev.commit.author;
      }

      if (role === this._CHANGE_ROLE.COMMITTER &&
          rev.commit && rev.commit.committer &&
          change.owner.email !== rev.commit.committer.email) {
        return rev.commit.committer;
      }

      return null;
    },

    _computeParents(change, revision) {
      if (!revision || !revision.commit) {
        if (!change || !change.current_revision) { return []; }
        revision = change.revisions[change.current_revision];
        if (!revision || !revision.commit) { return []; }
      }
      return revision.commit.parents;
    },

    _computeParentsLabel(parents) {
      return parents && parents.length > 1 ? 'Parents' : 'Parent';
    },

    _computeParentListClass(parents, parentIsCurrent) {
      // Undefined check for polymer 2
      if (parents === undefined || parentIsCurrent === undefined) {
        return '';
      }

      return [
        'parentList',
        parents && parents.length > 1 ? 'merge' : 'nonMerge',
        parentIsCurrent ? 'current' : 'notCurrent',
      ].join(' ');
    },

    _computeIsMutable(account) {
      return !!Object.keys(account).length;
    },

    editTopic() {
      if (this._topicReadOnly || this.change.topic) { return; }
      // Cannot use `this.$.ID` syntax because the element exists inside of a
      // dom-if.
      this.$$('.topicEditableLabel').open();
    },

    _getReviewerSuggestionsProvider(change) {
      const provider = GrReviewerSuggestionsProvider.create(this.$.restAPI,
          change._number, Gerrit.SUGGESTIONS_PROVIDERS_USERS_TYPES.ANY);
      provider.init();
      return provider;
    },
  });
})();
