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

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: 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 !== undefined) {
          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);
          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?: 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;
  }

  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
    )}`;
  }
}
