/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {BLANK_LINE, GrDiffLine, GrDiffLineType} from './gr-diff-line';
import {LineRange, Side} from '../../../api/diff';
import {LineNumber} from './gr-diff-line';
import {assertIsDefined, check} from '../../../utils/common-util';

export enum GrDiffGroupType {
  /** Unchanged context. */
  BOTH = 'both',

  /** A widget used to show more context. */
  CONTEXT_CONTROL = 'contextControl',

  /** Added, removed or modified chunk. */
  DELTA = 'delta',
}

export interface GrDiffLinePair {
  left: GrDiffLine;
  right: GrDiffLine;
}

/**
 * Hides lines in the given range behind a context control group.
 *
 * Groups that would be partially visible are split into their visible and
 * hidden parts, respectively.
 * The groups need to be "common groups", meaning they have to have either
 * originated from an `ab` chunk, or from an `a`+`b` chunk with
 * `common: true`.
 *
 * If the hidden range is 3 lines or less, nothing is hidden and no context
 * control group is created.
 *
 * @param groups Common groups, ordered by their line ranges.
 * @param hiddenStart The first element to be hidden, as a
 *     non-negative line number offset relative to the first group's start
 *     line, left and right respectively.
 * @param hiddenEnd The first visible element after the hidden range,
 *     as a non-negative line number offset relative to the first group's
 *     start line, left and right respectively.
 */
export function hideInContextControl(
  groups: readonly GrDiffGroup[],
  hiddenStart: number,
  hiddenEnd: number
): GrDiffGroup[] {
  if (groups.length === 0) return [];
  // Clamp hiddenStart and hiddenEnd - inspired by e.g. substring
  hiddenStart = Math.max(hiddenStart, 0);
  hiddenEnd = Math.max(hiddenEnd, hiddenStart);

  let before: GrDiffGroup[] = [];
  let hidden = groups;
  let after: readonly GrDiffGroup[] = [];

  const numHidden = hiddenEnd - hiddenStart;

  // Showing a context control row for less than 4 lines does not make much,
  // because then that row would consume as much space as the collapsed code.
  if (numHidden > 3) {
    if (hiddenStart) {
      [before, hidden] = _splitCommonGroups(hidden, hiddenStart);
    }
    if (hiddenEnd) {
      let beforeLength = 0;
      if (before.length > 0) {
        const beforeStart = before[0].lineRange.left.start_line;
        const beforeEnd = before[before.length - 1].lineRange.left.end_line;
        beforeLength = beforeEnd - beforeStart + 1;
      }
      [hidden, after] = _splitCommonGroups(hidden, hiddenEnd - beforeLength);
    }
  } else {
    [hidden, after] = [[], hidden];
  }

  const result = [...before];
  if (hidden.length) {
    result.push(
      new GrDiffGroup({
        type: GrDiffGroupType.CONTEXT_CONTROL,
        contextGroups: [...hidden],
      })
    );
  }
  result.push(...after);
  return result;
}

/**
 * Splits a group in two, defined by leftSplit and rightSplit. Primarily to be
 * used in function _splitCommonGroups
 * Groups with some lines before and some lines after the split will be split
 * into two groups, which will be put into the first and second list.
 *
 * @param group The group to be split in two
 * @param leftSplit The line number relative to the split on the left side
 * @param rightSplit The line number relative to the split on the right side
 * @return two new groups, one before the split and another after it
 */
function _splitGroupInTwo(
  group: GrDiffGroup,
  leftSplit: number,
  rightSplit: number
) {
  let beforeSplit: GrDiffGroup | undefined;
  let afterSplit: GrDiffGroup | undefined;
  // split line is in the middle of a group, we need to break the group
  // in lines before and after the split.
  if (group.skip) {
    // Currently we assume skip chunks "refuse" to be split. Expanding this
    // group will in the future mean load more data - and therefore we want to
    // fire an event when user wants to do it.
    const closerToStartThanEnd =
      leftSplit - group.lineRange.left.start_line <
      group.lineRange.right.end_line - leftSplit;
    if (closerToStartThanEnd) {
      afterSplit = group;
    } else {
      beforeSplit = group;
    }
  } else {
    const before = [];
    const after = [];
    for (const line of group.lines) {
      if (
        (line.beforeNumber && line.beforeNumber < leftSplit) ||
        (line.afterNumber && line.afterNumber < rightSplit)
      ) {
        before.push(line);
      } else {
        after.push(line);
      }
    }
    if (before.length) {
      beforeSplit =
        before.length === group.lines.length
          ? group
          : group.cloneWithLines(before);
    }
    if (after.length) {
      afterSplit =
        after.length === group.lines.length
          ? group
          : group.cloneWithLines(after);
    }
  }
  return {beforeSplit, afterSplit};
}

/**
 * Splits a list of common groups into two lists of groups.
 *
 * Groups where all lines are before or all lines are after the split will be
 * retained as is and put into the first or second list respectively. Groups
 * with some lines before and some lines after the split will be split into
 * two groups, which will be put into the first and second list.
 *
 * @param split A line number offset relative to the first group's
 *     start line at which the groups should be split.
 * @return The outer array has 2 elements, the
 *   list of groups before and the list of groups after the split.
 */
function _splitCommonGroups(
  groups: readonly GrDiffGroup[],
  split: number
): GrDiffGroup[][] {
  if (groups.length === 0) return [[], []];
  const leftSplit = groups[0].lineRange.left.start_line + split;
  const rightSplit = groups[0].lineRange.right.start_line + split;

  const beforeGroups = [];
  const afterGroups = [];
  for (const group of groups) {
    const isCompletelyBefore =
      group.lineRange.left.end_line < leftSplit ||
      group.lineRange.right.end_line < rightSplit;
    const isCompletelyAfter =
      leftSplit <= group.lineRange.left.start_line ||
      rightSplit <= group.lineRange.right.start_line;
    if (isCompletelyBefore) {
      beforeGroups.push(group);
    } else if (isCompletelyAfter) {
      afterGroups.push(group);
    } else {
      const {beforeSplit, afterSplit} = _splitGroupInTwo(
        group,
        leftSplit,
        rightSplit
      );
      if (beforeSplit) {
        beforeGroups.push(beforeSplit);
      }
      if (afterSplit) {
        afterGroups.push(afterSplit);
      }
    }
  }
  return [beforeGroups, afterGroups];
}

export interface GrMoveDetails {
  changed: boolean;
  range?: {
    start: number;
    end: number;
  };
}

/** A chunk of the diff that should be rendered together. */
export class GrDiffGroup {
  constructor(
    options:
      | {
          type: GrDiffGroupType.BOTH | GrDiffGroupType.DELTA;
          lines?: GrDiffLine[];
          skip?: undefined;
          moveDetails?: GrMoveDetails;
          dueToRebase?: boolean;
          ignoredWhitespaceOnly?: boolean;
          keyLocation?: boolean;
        }
      | {
          type: GrDiffGroupType.BOTH | GrDiffGroupType.DELTA;
          lines?: undefined;
          skip: number;
          offsetLeft: number;
          offsetRight: number;
          moveDetails?: GrMoveDetails;
          dueToRebase?: boolean;
          ignoredWhitespaceOnly?: boolean;
          keyLocation?: boolean;
        }
      | {
          type: GrDiffGroupType.CONTEXT_CONTROL;
          contextGroups: GrDiffGroup[];
        }
  ) {
    this.type = options.type;
    switch (options.type) {
      case GrDiffGroupType.BOTH:
      case GrDiffGroupType.DELTA: {
        this.moveDetails = options.moveDetails;
        this.dueToRebase = options.dueToRebase ?? false;
        this.ignoredWhitespaceOnly = options.ignoredWhitespaceOnly ?? false;
        this.keyLocation = options.keyLocation ?? false;
        if (options.skip && options.lines) {
          throw new Error('Cannot set skip and lines');
        }
        this.skip = options.skip;
        if (options.skip) {
          this.lineRange = {
            left: {
              start_line: options.offsetLeft,
              end_line: options.offsetLeft + options.skip - 1,
            },
            right: {
              start_line: options.offsetRight,
              end_line: options.offsetRight + options.skip - 1,
            },
          };
        } else {
          assertIsDefined(options.lines);
          check(options.lines.length > 0, 'diff group must have lines');
          for (const line of options.lines) {
            this.addLine(line);
          }
        }
        break;
      }
      case GrDiffGroupType.CONTEXT_CONTROL: {
        this.contextGroups = options.contextGroups;
        if (this.contextGroups.length > 0) {
          const firstGroup = this.contextGroups[0];
          const lastGroup = this.contextGroups[this.contextGroups.length - 1];
          this.lineRange = {
            left: {
              start_line: firstGroup.lineRange.left.start_line,
              end_line: lastGroup.lineRange.left.end_line,
            },
            right: {
              start_line: firstGroup.lineRange.right.start_line,
              end_line: lastGroup.lineRange.right.end_line,
            },
          };
        }
        break;
      }
      default:
        throw new Error(`Unknown group type: ${this.type}`);
    }
  }

  readonly type: GrDiffGroupType;

  readonly dueToRebase: boolean = false;

  /**
   * True means all changes in this line are whitespace changes that should
   * not be highlighted as changed as per the user settings.
   */
  readonly ignoredWhitespaceOnly: boolean = false;

  /**
   * True means it should not be collapsed (because it was in the URL, or
   * there is a comment on that line)
   */
  readonly keyLocation: boolean = false;

  /**
   * Once rendered the diff builder sets this to the diff section element.
   */
  element?: HTMLElement;

  readonly lines: GrDiffLine[] = [];

  readonly adds: GrDiffLine[] = [];

  readonly removes: GrDiffLine[] = [];

  readonly contextGroups: GrDiffGroup[] = [];

  readonly skip?: number;

  /** Both start and end line are inclusive. */
  readonly lineRange: {[side in Side]: LineRange} = {
    [Side.LEFT]: {start_line: 0, end_line: 0},
    [Side.RIGHT]: {start_line: 0, end_line: 0},
  };

  readonly moveDetails?: GrMoveDetails;

  /**
   * Creates a new group with the same properties but different lines.
   *
   * The element property is not copied, because the original element is still a
   * rendering of the old lines, so that would not make sense.
   */
  cloneWithLines(lines: GrDiffLine[]): GrDiffGroup {
    if (
      this.type !== GrDiffGroupType.BOTH &&
      this.type !== GrDiffGroupType.DELTA
    ) {
      throw new Error('Cannot clone context group with lines');
    }
    const group = new GrDiffGroup({
      type: this.type,
      lines,
      dueToRebase: this.dueToRebase,
      ignoredWhitespaceOnly: this.ignoredWhitespaceOnly,
    });
    return group;
  }

  private addLine(line: GrDiffLine) {
    this.lines.push(line);

    const notDelta =
      this.type === GrDiffGroupType.BOTH ||
      this.type === GrDiffGroupType.CONTEXT_CONTROL;
    if (
      notDelta &&
      (line.type === GrDiffLineType.ADD || line.type === GrDiffLineType.REMOVE)
    ) {
      throw Error('Cannot add delta line to a non-delta group.');
    }

    if (line.type === GrDiffLineType.ADD) {
      this.adds.push(line);
    } else if (line.type === GrDiffLineType.REMOVE) {
      this.removes.push(line);
    }
    this._updateRangeWithNewLine(line);
  }

  getSideBySidePairs(): GrDiffLinePair[] {
    if (
      this.type === GrDiffGroupType.BOTH ||
      this.type === GrDiffGroupType.CONTEXT_CONTROL
    ) {
      return this.lines.map(line => {
        return {
          left: line,
          right: line,
        };
      });
    }

    const pairs: GrDiffLinePair[] = [];
    let i = 0;
    let j = 0;
    while (i < this.removes.length || j < this.adds.length) {
      pairs.push({
        left: this.removes[i] || BLANK_LINE,
        right: this.adds[j] || BLANK_LINE,
      });
      i++;
      j++;
    }
    return pairs;
  }

  /** Returns true if it is, or contains, a skip group. */
  hasSkipGroup() {
    return !!this.skip || this.contextGroups?.some(g => !!g.skip);
  }

  containsLine(side: Side, line: LineNumber) {
    if (line === 'FILE' || line === 'LOST') {
      // For FILE and LOST, beforeNumber and afterNumber are the same
      return this.lines[0]?.beforeNumber === line;
    }
    const lineRange = this.lineRange[side];
    return lineRange.start_line <= line && line <= lineRange.end_line;
  }

  private _updateRangeWithNewLine(line: GrDiffLine) {
    if (
      line.beforeNumber === 'FILE' ||
      line.afterNumber === 'FILE' ||
      line.beforeNumber === 'LOST' ||
      line.afterNumber === 'LOST'
    ) {
      return;
    }

    if (line.type === GrDiffLineType.ADD || line.type === GrDiffLineType.BOTH) {
      if (
        this.lineRange.right.start_line === 0 ||
        line.afterNumber < this.lineRange.right.start_line
      ) {
        this.lineRange.right.start_line = line.afterNumber;
      }
      if (line.afterNumber > this.lineRange.right.end_line) {
        this.lineRange.right.end_line = line.afterNumber;
      }
    }

    if (
      line.type === GrDiffLineType.REMOVE ||
      line.type === GrDiffLineType.BOTH
    ) {
      if (
        this.lineRange.left.start_line === 0 ||
        line.beforeNumber < this.lineRange.left.start_line
      ) {
        this.lineRange.left.start_line = line.beforeNumber;
      }
      if (line.beforeNumber > this.lineRange.left.end_line) {
        this.lineRange.left.end_line = line.beforeNumber;
      }
    }
  }

  /**
   * Determines whether the group is either totally an addition or totally
   * a removal.
   */
  isTotal(): boolean {
    return (
      this.type === GrDiffGroupType.DELTA &&
      (!this.adds.length || !this.removes.length) &&
      !(!this.adds.length && !this.removes.length)
    );
  }
}
