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

export enum GrDiffGroupType {
  /** A group of unchanged diff lines. */
  BOTH = 'both',

  /**
   * A context control group "hides" other diff groups in its `contextGroups` field.
   */
  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 hiddenEndLeft The first visible element after the hidden range,
 *     as a non-negative line number offset for left side relative to the first
 *     group's start line.
 * @param hiddenEndRight The first visible element after the hidden range,
 *     as a non-negative line number offset for right side relative to the first
 *     group's start line. If not provided hiddenEndLeft will be used.
 */
export function hideInContextControl(
  groups: readonly GrDiffGroup[],
  hiddenStart: number,
  hiddenEndLeft: number,
  hiddenEndRight?: number
): GrDiffGroup[] {
  if (groups.length === 0) return [];
  // Clamp hiddenStart and hiddenEnd - inspired by e.g. substring
  hiddenStart = Math.max(hiddenStart, 0);
  hiddenEndLeft = Math.max(hiddenEndLeft, hiddenStart);
  hiddenEndRight = Math.max(hiddenEndRight ?? hiddenEndLeft, hiddenStart);

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

  const numHiddenLeft = hiddenEndLeft - hiddenStart;
  const numHiddenRight = hiddenEndRight - 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 (numHiddenLeft > 3 && numHiddenRight > 3) {
    if (hiddenStart) {
      [before, hidden] = splitCommonGroups(hidden, hiddenStart, hiddenStart);
    }
    if (hiddenEndLeft && hiddenEndRight) {
      let beforeLengthLeft = 0;
      let beforeLengthRight = 0;
      if (before.length > 0) {
        const beforeStartLeft = before[0].lineRange.left.start_line;
        const beforeEndLeft = before[before.length - 1].lineRange.left.end_line;
        beforeLengthLeft = beforeEndLeft - beforeStartLeft + 1;

        const beforeStartRight = before[0].lineRange.right.start_line;
        const beforeEndRight =
          before[before.length - 1].lineRange.right.end_line;
        beforeLengthRight = beforeEndRight - beforeStartRight + 1;
      }
      [hidden, after] = splitCommonGroups(
        hidden,
        hiddenEndLeft - beforeLengthLeft,
        hiddenEndRight - beforeLengthRight
      );
    }
  } 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 &&
          typeof line.beforeNumber === 'number' &&
          line.beforeNumber < leftSplit) ||
        (line.afterNumber &&
          typeof line.afterNumber === 'number' &&
          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. Groups with
 * type DELTA which are not common will not be split.
 *
 * @param splitLeft A line number offset for left side relative to the first
 *     group's start line at which the groups should be split.
 * @param splitRight A line number offset for right side 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[],
  splitLeft: number,
  splitRight: number
): GrDiffGroup[][] {
  if (groups.length === 0) return [[], []];
  const leftSplit = groups[0].lineRange.left.start_line + splitLeft;
  const rightSplit = groups[0].lineRange.right.start_line + splitRight;
  let isSplitDone = false;
  const beforeGroups = [];
  const afterGroups = [];
  for (const group of groups) {
    if (isSplitDone) {
      afterGroups.push(group);
    } else if (
      group.type === GrDiffGroupType.DELTA &&
      !group.ignoredWhitespaceOnly
    ) {
      beforeGroups.push(group);
    } else {
      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);
        }
        isSplitDone = true;
      }
    }
  }
  return [beforeGroups, afterGroups];
}

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

/**
 * A chunk of the diff that should be rendered together. Typically corresponds
 * to a gr-diff-section. It mostly just contains an array of diff `lines`.
 *
 * A group of type CONTEXT_CONTROL does not contain any lines directly, but
 * "hides" other groups in `contextGroups`, which the user can expand.
 */
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: SkipInfo;
          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 !== undefined) {
          const skip = normalizeSkipInfo(options.skip);
          this.lineRange = {
            left: {
              start_line: options.offsetLeft,
              end_line: options.offsetLeft + skip.left - 1,
            },
            right: {
              start_line: options.offsetRight,
              end_line: options.offsetRight + skip.right - 1,
            },
          };
        } else {
          assertIsDefined(options.lines);
          assert(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;

  readonly lines: GrDiffLine[] = [];

  readonly adds: GrDiffLine[] = [];

  readonly removes: GrDiffLine[] = [];

  /**
   * Only set, iff type is CONTEXT_CONTROL.
   *
   * A CONTEXT_CONTROL group "hides" other groups that the user may expand.
   * This field contains those hidden groups.
   */
  readonly contextGroups: GrDiffGroup[] = [];

  readonly skip?: SkipInfo;

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

  getUnifiedPairs(): GrDiffLinePair[] {
    return this.lines
      .map(line => {
        if (line.type === GrDiffLineType.ADD) {
          return {left: BLANK_LINE, right: line};
        }
        if (line.type === GrDiffLineType.REMOVE) {
          if (this.ignoredWhitespaceOnly) return undefined;
          return {left: line, right: BLANK_LINE};
        }
        return {left: line, right: line};
      })
      .filter(isDefined);
  }

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

  /** Returns true if it contains a DELTA group excluding whitespace only
   * changes.
   */
  hasNonCommonDeltaGroup() {
    return this.contextGroups?.some(
      g => g.type === GrDiffGroupType.DELTA && !g.ignoredWhitespaceOnly
    );
  }

  containsLine(side: Side, line: LineNumber) {
    if (typeof line !== 'number') {
      // 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;
  }

  startLine(side: Side): LineNumber {
    // For both CONTEXT_CONTROL groups and SKIP groups the `lines` array will
    // be empty. So we have to use `lineRange` instead of looking at the first
    // line.
    if (
      this.type === GrDiffGroupType.CONTEXT_CONTROL ||
      this.skip !== undefined
    ) {
      return side === Side.LEFT
        ? this.lineRange.left.start_line
        : this.lineRange.right.start_line;
    }
    // For "normal" groups we could also use the `lineRange`, but for FILE or
    // LOST lines we want to return FILE or LOST. The `lineRange` contains
    // numbers only.
    return this.lines[0].lineNumber(side);
  }

  private _updateRangeWithNewLine(line: GrDiffLine) {
    if (typeof line.beforeNumber !== 'number') return;
    if (typeof line.afterNumber !== 'number') 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)
    );
  }

  id() {
    return `${this.type} ${this.startLine(Side.LEFT)}  ${this.startLine(
      Side.RIGHT
    )}`;
  }
}
