/**
 * @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';
import {untilRendered} from '../../../utils/dom-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 !== 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);
          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;
      }
    }
  }

  async waitUntilRendered() {
    const lineNumber = this.lines[0]?.beforeNumber;
    // The LOST or FILE lines may be hidden and thus never resolve an
    // untilRendered() promise.
    if (
      this.skip ||
      lineNumber === 'LOST' ||
      lineNumber === 'FILE' ||
      this.type === GrDiffGroupType.CONTEXT_CONTROL
    ) {
      return Promise.resolve();
    }
    assertIsDefined(this.element);
    await untilRendered(this.element);
  }

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