/**
 * @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.
 */
import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-ranged-comment-layer_html';
import {GrDiffLine, GrDiffLineType} from '../gr-diff/gr-diff-line';
import {strToClassName} from '../../../utils/dom-util';
import {customElement, property, observe} from '@polymer/decorators';
import {Side} from '../../../constants/constants';
import {
  PolymerDeepPropertyChange,
  PolymerSpliceChange,
} from '@polymer/polymer/interfaces';
import {CommentRange} from '../../../types/common';
import {DiffLayer, DiffLayerListener} from '../../../types/types';
import {isLongCommentRange} from '../gr-diff/gr-diff-utils';

/**
 * Enhanced CommentRange by UI state. Interface for incoming ranges set from the
 * outside.
 *
 * TODO(TS): Unify with what is used in gr-diff when these objects are created.
 */
export interface CommentRangeLayer {
  side: Side;
  range: CommentRange;
  hovering: boolean;
  rootId: string;
}

/**
 * This class breaks down all comment ranges into individual line segment
 * highlights.
 */
interface CommentRangeLineLayer {
  hovering: boolean;
  longRange: boolean;
  rootId: string;
  start: number;
  end: number;
}

type LinesMap = {
  [line in number]: CommentRangeLineLayer[];
};

type RangesMap = {
  [side in Side]: LinesMap;
};

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

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

@customElement('gr-ranged-comment-layer')
export class GrRangedCommentLayer extends PolymerElement implements DiffLayer {
  static get template() {
    return htmlTemplate;
  }

  /**
   * 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
   */

  @property({type: Array})
  commentRanges: CommentRangeLayer[] = [];

  @property({type: Array})
  _listeners: DiffLayerListener[] = [];

  @property({type: Object})
  _rangesMap: RangesMap = {left: {}, right: {}};

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

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

    for (const range of ranges) {
      GrAnnotation.annotateElement(
        el,
        range.start,
        range.end - range.start,
        (range.hovering
          ? HOVER_HIGHLIGHT
          : range.longRange
          ? RANGE_BASE_ONLY
          : RANGE_HIGHLIGHT) + ` ${strToClassName(range.rootId)}`
      );
    }
  }

  /**
   * Register a listener for layer updates.
   */
  addListener(listener: DiffLayerListener) {
    this._listeners.push(listener);
  }

  removeListener(listener: DiffLayerListener) {
    this._listeners = this._listeners.filter(f => f !== listener);
  }

  /**
   * Notify Layer listeners of changes to annotations.
   */
  _notifyUpdateRange(start: number, end: number, side: 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.
   */
  @observe('commentRanges.*')
  _handleCommentRangesChange(
    record: PolymerDeepPropertyChange<
      CommentRangeLayer[],
      PolymerSpliceChange<CommentRangeLayer[]>
    >
  ) {
    if (!record) return;

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

    // 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, rootId} = this.get(match[1]);

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

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

  _updateRangesMap(options: {
    side: Side;
    range: CommentRange;
    hovering: boolean;
    operation: (
      forLine: CommentRangeLineLayer[],
      start: number,
      end: number,
      hovering: boolean
    ) => void;
    skipLayerUpdate?: boolean;
  }) {
    const {side, range, hovering, operation, skipLayerUpdate} = options;
    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);
    }
    if (!skipLayerUpdate) {
      this._notifyUpdateRange(range.start_line, range.end_line, side);
    }
  }

  _getRangesForLine(line: GrDiffLine, side: Side) {
    const lineNum = side === Side.LEFT ? line.beforeNumber : line.afterNumber;
    const ranges: CommentRangeLineLayer[] =
      this.get(['_rangesMap', side, lineNum]) || [];
    return (
      ranges
        .map(range => {
          // Make a copy, so that the normalization below does not mess with
          // our map.
          range = {...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))
    );
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-ranged-comment-layer': GrRangedCommentLayer;
  }
}
