<!--
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.
-->
<script>
(function(window) {
  'use strict';

  // Tags identifying ChangeMessages that move change into WIP state.
  const WIP_TAGS = [
    'autogenerated:gerrit:newWipPatchSet',
    'autogenerated:gerrit:setWorkInProgress',
  ];

  // Tags identifying ChangeMessages that move change out of WIP state.
  const READY_TAGS = [
    'autogenerated:gerrit:setReadyForReview',
  ];

  /** @polymerBehavior Gerrit.PatchSetBehavior */
  const PatchSetBehavior = {
    /**
     * Given an object of revisions, get a particular revision based on patch
     * num.
     *
     * @param {Object} revisions The object of revisions given by the API
     * @param {number|string} patchNum The number index of the revision
     * @return {Object} The correspondent revision obj from {revisions}
     */
    getRevisionByPatchNum(revisions, patchNum) {
      patchNum = parseInt(patchNum, 10);
      for (const rev in revisions) {
        if (revisions.hasOwnProperty(rev) &&
            revisions[rev]._number === patchNum) {
          return revisions[rev];
        }
      }
    },

    /**
     * Construct a chronological list of patch sets derived from change details.
     * Each element of this list is an object with the following properties:
     *
     *   * num {number} The number identifying the patch set
     *   * desc {!string} Optional patch set description
     *   * wip {boolean} If true, this patch set was never subject to review.
     *
     * The wip property is determined by the change's current work_in_progress
     * property and its log of change messages.
     *
     * @param {Object} change The change details
     * @return {Array<Object>} Sorted list of patch set objects, as described
     *     above
     */
    computeAllPatchSets(change) {
      if (!change) { return []; }
      const patchNums = [];
      for (const commit in change.revisions) {
        if (change.revisions.hasOwnProperty(commit)) {
          patchNums.push({
            num: change.revisions[commit]._number,
            desc: change.revisions[commit].description,
          });
        }
      }
      patchNums.sort((a, b) => { return a.num - b.num; });
      return this._computeWipForPatchSets(change, patchNums);
    },

    /**
     * Populate the wip properties of the given list of patch sets.
     *
     * @param {Object} change The change details
     * @param {Array<Object>} patchNums Sorted list of patch set objects, as
     *     generated by computeAllPatchSets
     * @return {Array<Object>} The given list of patch set objects, with the
     *     wip property set on each of them
     */
    _computeWipForPatchSets(change, patchNums) {
      if (!change.messages || !change.messages.length) {
        return patchNums;
      }
      const psWip = {};
      let wip = change.work_in_progress;
      for (let i = 0; i < change.messages.length; i++) {
        const msg = change.messages[i];
        if (WIP_TAGS.includes(msg.tag)) {
          wip = true;
        } else if (READY_TAGS.includes(msg.tag)) {
          wip = false;
        }
        if (psWip[msg._revision_number] !== false) {
          psWip[msg._revision_number] = wip;
        }
      }

      for (let i = 0; i < patchNums.length; i++) {
        patchNums[i].wip = psWip[patchNums[i].num];
      }
      return patchNums;
    },

    computeLatestPatchNum(allPatchSets) {
      if (!allPatchSets || !allPatchSets.length) { return undefined; }
      return allPatchSets[allPatchSets.length - 1].num;
    },

    /**
     * Check whether there is no newer patch than the latest patch that was
     * available when this change was loaded.
     * @return {Promise} A promise that yields true if the latest patch has been
     *     loaded, and false if a newer patch has been uploaded in the meantime.
     */
    fetchIsLatestKnown(change, restAPI) {
      const knownLatest = this.computeLatestPatchNum(
          this.computeAllPatchSets(change));
      return restAPI.getChangeDetail(change._number)
          .then(detail => {
            const actualLatest = this.computeLatestPatchNum(
                this.computeAllPatchSets(detail));
            return actualLatest <= knownLatest;
          });
    },
  };

  window.Gerrit = window.Gerrit || {};
  window.Gerrit.PatchSetBehavior = PatchSetBehavior;
})(window);
</script>
