/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
import {GrDiffLine, GrDiffLineType} from '../gr-diff/gr-diff-line';
import {strToClassName} from '../../../utils/dom-util';
import {Side} from '../../../constants/constants';
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;
  // New drafts don't have a rootId.
  rootId?: string;
}

/** Can be used for array functions like `some()`. */
function equals(a: CommentRangeLayer) {
  return (b: CommentRangeLayer) => id(a) === id(b);
}

function id(r: CommentRangeLayer): string {
  if (r.rootId) return r.rootId;
  return `${r.side}-${r.range.start_line}-${r.range.start_character}-${r.range.end_line}-${r.range.end_character}`;
}

/**
 * This class breaks down all comment ranges into individual line segment
 * highlights.
 */
interface CommentRangeLineLayer {
  longRange: boolean;
  id: string;
  // start char (0-based)
  start: number;
  // end char (0-based)
  end: number;
}

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

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

const RANGE_BASE_ONLY = 'style-scope gr-diff range';
const RANGE_HIGHLIGHT = 'style-scope gr-diff range rangeHighlight';
// Note that there is also `rangeHoverHighlight` being set by GrDiffHighlight.

export class GrRangedCommentLayer implements DiffLayer {
  private knownRanges: CommentRangeLayer[] = [];

  private listeners: DiffLayerListener[] = [];

  private rangesMap: RangesMap = {left: {}, right: {}};

  /**
   * 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') !== Side.RIGHT)
    ) {
      ranges = this.getRangesForLine(line, Side.LEFT);
    }
    if (
      line.type === GrDiffLineType.ADD ||
      (line.type === GrDiffLineType.BOTH &&
        el.getAttribute('data-side') !== Side.LEFT)
    ) {
      ranges = this.getRangesForLine(line, Side.RIGHT);
    }

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

  /**
   * 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.
   */
  private notifyUpdateRange(start: number, end: number, side: Side) {
    for (const listener of this.listeners) {
      listener(start, end, side);
    }
  }

  updateRanges(newRanges: CommentRangeLayer[]) {
    for (const newRange of newRanges) {
      if (this.knownRanges.some(equals(newRange))) continue;
      this.addRange(newRange);
    }

    for (const knownRange of this.knownRanges) {
      if (newRanges.some(equals(knownRange))) continue;
      this.removeRange(knownRange);
    }

    this.knownRanges = [...newRanges];
  }

  private addRange(commentRange: CommentRangeLayer) {
    const {side, range} = commentRange;
    const longRange = isLongCommentRange(range);
    this.updateRangesMap({
      side,
      range,
      operation: (forLine, startChar, endChar) => {
        forLine.push({
          start: startChar,
          end: endChar,
          id: id(commentRange),
          longRange,
        });
      },
    });
  }

  private removeRange(commentRange: CommentRangeLayer) {
    const {side, range} = commentRange;
    this.updateRangesMap({
      side,
      range,
      operation: forLine => {
        const index = forLine.findIndex(
          lineRange => id(commentRange) === lineRange.id
        );
        if (index > -1) forLine.splice(index, 1);
      },
    });
  }

  private updateRangesMap(options: {
    side: Side;
    range: CommentRange;
    operation: (
      forLine: CommentRangeLineLayer[],
      start: number,
      end: number
    ) => void;
  }) {
    const {side, range, operation} = 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);
    }
    this.notifyUpdateRange(range.start_line, range.end_line, side);
  }

  // visible for testing
  getRangesForLine(line: GrDiffLine, side: Side): CommentRangeLineLayer[] {
    const lineNum = side === Side.LEFT ? line.beforeNumber : line.afterNumber;
    if (lineNum === 'FILE' || lineNum === 'LOST') return [];
    const ranges: CommentRangeLineLayer[] = this.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;
      }

      return range;
    });
  }
}
