/**
 * @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 HOVER_PATH_PATTERN = /^comments\.(left|right)\.\#(\d+)\.__hovering$/;
  const SPLICE_PATH_PATTERN = /^comments\.(left|right)\.splices$/;

  const RANGE_HIGHLIGHT = 'range';
  const HOVER_HIGHLIGHT = 'rangeHighlight';

  const NORMALIZE_RANGE_EVENT = 'normalize-range';

  Polymer({
    is: 'gr-ranged-comment-layer',

    properties: {
      comments: Object,
      _listeners: {
        type: Array,
        value() { return []; },
      },
      _commentMap: {
        type: Object,
        value() { return {left: [], right: []}; },
      },
    },

    observers: [
      '_handleCommentChange(comments.*)',
    ],

    /**
     * Layer method to add annotations to a line.
     * @param {!HTMLElement} el The DIV.contentText element to apply the
     *     annotation to.
     * @param {!Object} line The line object. (GrDiffLine)
     */
    annotate(el, 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 comments by updating the comment maps and by
     * emitting appropriate update notifications.
     * @param {Object} record The change record.
     */
    _handleCommentChange(record) {
      if (!record.path) { return; }

      // If the entire set of comments was changed.
      if (record.path === 'comments') {
        this._commentMap.left = this._computeCommentMap(this.comments.left);
        this._commentMap.right = this._computeCommentMap(this.comments.right);
        return;
      }

      // If the change only changed the `hovering` property of a comment.
      let match = record.path.match(HOVER_PATH_PATTERN);
      let side;

      if (match) {
        side = match[1];
        const index = match[2];
        const comment = this.comments[side][index];
        if (comment && comment.range) {
          this._commentMap[side] = this._computeCommentMap(this.comments[side]);
          this._notifyUpdateRange(
              comment.range.start_line, comment.range.end_line, side);
        }
        return;
      }

      // If comments were spliced in or out.
      match = record.path.match(SPLICE_PATH_PATTERN);
      if (match) {
        side = match[1];
        this._commentMap[side] = this._computeCommentMap(this.comments[side]);
        this._handleCommentSplice(record.value, side);
      }
    },

    /**
     * Take a list of comments and return a sparse list mapping line numbers to
     * partial ranges. Uses an end-character-index of -1 to indicate the end of
     * the line.
     * @param {?} commentList The list of comments.
     *    Getting this param to match closure requirements caused problems.
     * @return {!Object} The sparse list.
     */
    _computeCommentMap(commentList) {
      const result = {};
      for (const comment of commentList) {
        if (!comment.range) { continue; }
        const range = comment.range;
        for (let line = range.start_line; line <= range.end_line; line++) {
          if (!result[line]) { result[line] = []; }
          result[line].push({
            comment,
            start: line === range.start_line ? range.start_character : 0,
            end: line === range.end_line ? range.end_character : -1,
          });
        }
      }
      return result;
    },

    /**
     * Translate a splice record into range update notifications.
     */
    _handleCommentSplice(record, side) {
      if (!record || !record.indexSplices) { return; }

      for (const splice of record.indexSplices) {
        const ranges = splice.removed.length ?
            splice.removed.map(c => { return c.range; }) :
            [splice.object[splice.index].range];
        for (const range of ranges) {
          if (!range) { continue; }
          this._notifyUpdateRange(range.start_line, range.end_line, side);
        }
      }
    },

    _getRangesForLine(line, side) {
      const lineNum = side === 'left' ? line.beforeNumber : line.afterNumber;
      const ranges = this.get(['_commentMap', side, lineNum]) || [];
      return ranges
          .map(range => {
            range = {
              start: range.start,
              end: range.end === -1 ? line.text.length : range.end,
              hovering: !!range.comment.__hovering,
            };

            // 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.$.reporting.reportInteraction(NORMALIZE_RANGE_EVENT,
                  'Modified invalid comment range on l.' + lineNum +
                  ' of the ' + side + ' side');
            }

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