<!--
@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.
-->
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../base-url-behavior/base-url-behavior.html">
<script>
(function(window) {
  'use strict';

  window.Gerrit = window.Gerrit || {};

  /** @polymerBehavior Gerrit.RESTClientBehavior */
  Gerrit.RESTClientBehavior = [{
    ChangeDiffType: {
      ADDED: 'ADDED',
      COPIED: 'COPIED',
      DELETED: 'DELETED',
      MODIFIED: 'MODIFIED',
      RENAMED: 'RENAMED',
      REWRITE: 'REWRITE',
    },

    ChangeStatus: {
      ABANDONED: 'ABANDONED',
      MERGED: 'MERGED',
      NEW: 'NEW',
    },

    // Must be kept in sync with the ListChangesOption enum and protobuf.
    ListChangesOption: {
      LABELS: 0,
      DETAILED_LABELS: 8,

      // Return information on the current patch set of the change.
      CURRENT_REVISION: 1,
      ALL_REVISIONS: 2,

      // If revisions are included, parse the commit object.
      CURRENT_COMMIT: 3,
      ALL_COMMITS: 4,

      // If a patch set is included, include the files of the patch set.
      CURRENT_FILES: 5,
      ALL_FILES: 6,

      // If accounts are included, include detailed account info.
      DETAILED_ACCOUNTS: 7,

      // Include messages associated with the change.
      MESSAGES: 9,

      // Include allowed actions client could perform.
      CURRENT_ACTIONS: 10,

      // Set the reviewed boolean for the caller.
      REVIEWED: 11,

      // Include download commands for the caller.
      DOWNLOAD_COMMANDS: 13,

      // Include patch set weblinks.
      WEB_LINKS: 14,

      // Include consistency check results.
      CHECK: 15,

      // Include allowed change actions client could perform.
      CHANGE_ACTIONS: 16,

      // Include a copy of commit messages including review footers.
      COMMIT_FOOTERS: 17,

      // Include push certificate information along with any patch sets.
      PUSH_CERTIFICATES: 18,

      // Include change's reviewer updates.
      REVIEWER_UPDATES: 19,

      // Set the submittable boolean.
      SUBMITTABLE: 20,

      // If tracking ids are included, include detailed tracking ids info.
      TRACKING_IDS: 21,

      // Skip mergeability data.
      SKIP_MERGEABLE: 22,
    },

    listChangesOptionsToHex(...args) {
      let v = 0;
      for (let i = 0; i < args.length; i++) {
        v |= 1 << args[i];
      }
      return v.toString(16);
    },

    /**
     *  @return {string}
     */
    changeBaseURL(project, changeNum, patchNum) {
      let v = this.getBaseUrl() + '/changes/' +
         encodeURIComponent(project) + '~' + changeNum;
      if (patchNum) {
        v += '/revisions/' + patchNum;
      }
      return v;
    },

    changePath(changeNum) {
      return this.getBaseUrl() + '/c/' + changeNum;
    },

    changeIsOpen(change) {
      return change && change.status === this.ChangeStatus.NEW;
    },

    /**
     * @param {!Object} change
     * @param {!Object=} opt_options
     *
     * @return {!Array}
     */
    changeStatuses(change, opt_options) {
      const states = [];
      if (change.status === this.ChangeStatus.MERGED) {
        states.push('Merged');
      } else if (change.status === this.ChangeStatus.ABANDONED) {
        states.push('Abandoned');
      } else if (change.mergeable === false ||
          (opt_options && opt_options.mergeable === false)) {
        // 'mergeable' prop may not always exist (@see Issue 6819)
        states.push('Merge Conflict');
      }
      if (change.work_in_progress) { states.push('WIP'); }
      if (change.is_private) { states.push('Private'); }

      // If there are any pre-defined statuses, only return those. Otherwise,
      // will determine the derived status.
      if (states.length || !opt_options) { return states; }

      // If no missing requirements, either active or ready to submit.
      if (change.submittable && opt_options.submitEnabled) {
        states.push('Ready to submit');
      } else {
        // Otherwise it is active.
        states.push('Active');
      }
      return states;
    },

    /**
     * @param {!Object} change
     * @return {String}
     */
    changeStatusString(change) {
      return this.changeStatuses(change).join(', ');
    },
  },
    Gerrit.BaseUrlBehavior,
  ];
})(window);
</script>
