/**
 * @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 Defs = {};

  /**
   * @typedef {{
   *    message: string,
   *    icon: string,
   *    class: string,
   *  }}
   */
  Defs.PushCertificateValidation;

  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',
    _legacyUndefinedCheck: true,

    /**
     * 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 {Defs.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)',
      },

      /** @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.status);
    },

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

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

    _showTopicChip(changeRecord, settingTopic) {
      const hasTopic = !!changeRecord && !!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}));
            }
          });
    },

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

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

    _computeAssigneeReadOnly(mutable, change) {
      return !mutable ||
          !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 {?Defs.PushCertificateValidation} object representing data for
     *     the push validation.
     */
    _computePushCertificateValidation(serverConfig, change) {
      if (!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) {
      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}));
      }).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.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) {
      if (!change.current_revision ||
          !change.revisions[change.current_revision] ||
          !change.revisions[change.current_revision].commit) {
        return undefined;
      }
      return change.revisions[change.current_revision].commit.parents;
    },

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

    _computeParentListClass(parents, parentIsCurrent) {
      return [
        'parentList',
        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();
    },
  });
})();
