/**
 * @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';

  // Polymer 1 adds # before array's key, while Polymer 2 doesn't
  const HOVER_PATH_PATTERN = /^(commentRanges\.\#?\d+)\.hovering$/;

  const RANGE_HIGHLIGHT = 'style-scope gr-diff range';
  const HOVER_HIGHLIGHT = 'style-scope gr-diff rangeHighlight';

  class GrRangedCommentLayer extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    static get is() { return 'gr-ranged-comment-layer'; }
    /**
     * Fired when the range in a range comment was malformed and had to be
     * normalized.
     *
     * It's `detail` has a `lineNum` and `side` parameter.
     *
     * @event normalize-range
     */

    static get properties() {
      return {
      /** @type {!Array<!Gerrit.HoveredRange>} */
        commentRanges: Array,
        _listeners: {
          type: Array,
          value() { return []; },
        },
        _rangesMap: {
          type: Object,
          value() { return {left: {}, right: {}}; },
        },
      };
    }

    static get observers() {
      return [
        '_handleCommentRangesChange(commentRanges.*)',
      ];
    }

    get styleModuleName() {
      return 'gr-ranged-comment-styles';
    }

    /**
     * Layer method to add annotations to a line.
     * @param {!HTMLElement} el The DIV.contentText element to apply the
     *     annotation to.
     * @param {!HTMLElement} lineNumberEl
     * @param {!Object} line The line object. (GrDiffLine)
     */
    annotate(el, lineNumberEl, line) {
      let ranges = [];
      if (line.type === GrDiffLine.Type.REMOVE || (
        line.type === GrDiffLine.Type.BOTH &&
          el.getAttribute('data-side') !== 'right')) {
        ranges = ranges.concat(this._getRangesForLine(line, 'left'));
      }
      if (line.type === GrDiffLine.Type.ADD || (
        line.type === GrDiffLine.Type.BOTH &&
          el.getAttribute('data-side') !== 'left')) {
        ranges = ranges.concat(this._getRangesForLine(line, 'right'));
      }

      for (const range of ranges) {
        GrAnnotation.annotateElement(el, range.start,
            range.end - range.start,
            range.hovering ? HOVER_HIGHLIGHT : RANGE_HIGHLIGHT);
      }
    }

    /**
     * Register a listener for layer updates.
     * @param {function(number, number, string)} fn The update handler function.
     *     Should accept as arguments the line numbers for the start and end of
     *     the update and the side as a string.
     */
    addListener(fn) {
      this._listeners.push(fn);
    }

    /**
     * Notify Layer listeners of changes to annotations.
     * @param {number} start The line where the update starts.
     * @param {number} end The line where the update ends.
     * @param {string} side The side of the update. ('left' or 'right')
     */
    _notifyUpdateRange(start, end, side) {
      for (const listener of this._listeners) {
        listener(start, end, side);
      }
    }

    /**
     * Handle change in the ranges by updating the ranges maps and by
     * emitting appropriate update notifications.
     * @param {Object} record The change record.
     */
    _handleCommentRangesChange(record) {
      if (!record) return;

      // If the entire set of comments was changed.
      if (record.path === 'commentRanges') {
        this._rangesMap = {left: {}, right: {}};
        for (const {side, range, hovering} of record.value) {
          this._updateRangesMap(
              side, range, hovering, (forLine, start, end, hovering) => {
                forLine.push({start, end, hovering});
              });
        }
      }

      // If the change only changed the `hovering` property of a comment.
      const match = record.path.match(HOVER_PATH_PATTERN);
      if (match) {
        // The #number indicates the key of that item in the array
        // not the index, especially in polymer 1.
        const {side, range, hovering} = this.get(match[1]);

        this._updateRangesMap(
            side, range, hovering, (forLine, start, end, hovering) => {
              const index = forLine.findIndex(lineRange =>
                lineRange.start === start && lineRange.end === end);
              forLine[index].hovering = hovering;
            });
      }

      // If comments were spliced in or out.
      if (record.path === 'commentRanges.splices') {
        for (const indexSplice of record.value.indexSplices) {
          const removed = indexSplice.removed;
          for (const {side, range, hovering} of removed) {
            this._updateRangesMap(
                side, range, hovering, (forLine, start, end) => {
                  const index = forLine.findIndex(lineRange =>
                    lineRange.start === start && lineRange.end === end);
                  forLine.splice(index, 1);
                });
          }
          const added = indexSplice.object.slice(
              indexSplice.index, indexSplice.index + indexSplice.addedCount);
          for (const {side, range, hovering} of added) {
            this._updateRangesMap(
                side, range, hovering, (forLine, start, end, hovering) => {
                  forLine.push({start, end, hovering});
                });
          }
        }
      }
    }

    _updateRangesMap(side, range, hovering, operation) {
      const forSide = this._rangesMap[side] || (this._rangesMap[side] = {});
      for (let line = range.start_line; line <= range.end_line; line++) {
        const forLine = forSide[line] || (forSide[line] = []);
        const start = line === range.start_line ? range.start_character : 0;
        const end = line === range.end_line ? range.end_character : -1;
        operation(forLine, start, end, hovering);
      }
      this._notifyUpdateRange(range.start_line, range.end_line, side);
    }

    _getRangesForLine(line, side) {
      const lineNum = side === 'left' ? line.beforeNumber : line.afterNumber;
      const ranges = this.get(['_rangesMap', side, lineNum]) || [];
      return ranges
          .map(range => {
            // Make a copy, so that the normalization below does not mess with
            // our map.
            range = Object.assign({}, range);
            range.end = range.end === -1 ? line.text.length : range.end;

            // Normalize invalid ranges where the start is after the end but the
            // start still makes sense. Set the end to the end of the line.
            // @see Issue 5744
            if (range.start >= range.end && range.start < line.text.length) {
              range.end = line.text.length;
              this.dispatchEvent(new CustomEvent('normalize-range', {
                bubbles: true,
                composed: true,
                detail: {lineNum, side},
              }));
            }

            return range;
          })
          // Sort the ranges so that hovering highlights are on top.
          .sort((a, b) => a.hovering && !b.hovering ? 1 : 0);
    }
  }

  customElements.define(GrRangedCommentLayer.is, GrRangedCommentLayer);
})();
