/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {CommentRange} from '../../../types/common';
import {Side, SpecialFilePath} from '../../../constants/constants';
import {
  DiffContextExpandedExternalDetail,
  DiffPreferencesInfo,
  DiffResponsiveMode,
  DisplayLine,
  FILE,
  LOST,
  LineNumber,
  RenderPreferences,
} from '../../../api/diff';
import {GrDiffGroup} from './gr-diff-group';

/**
 * In JS, unicode code points above 0xFFFF occupy two elements of a string.
 * For example '𐀏'.length is 2. An occurrence of such a code point is called a
 * surrogate pair.
 *
 * This regex segments a string along tabs ('\t') and surrogate pairs, since
 * these are two cases where '1 char' does not automatically imply '1 column'.
 *
 * TODO: For human languages whose orthographies use combining marks, this
 * approach won't correctly identify the grapheme boundaries. In those cases,
 * a grapheme consists of multiple code points that should count as only one
 * character against the column limit. Getting that correct (if it's desired)
 * is probably beyond the limits of a regex, but there are nonstandard APIs to
 * do this, and proposed (but, as of Nov 2017, unimplemented) standard APIs.
 *
 * Further reading:
 *   On Unicode in JS: https://mathiasbynens.be/notes/javascript-unicode
 *   Graphemes: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
 *   A proposed JS API: https://github.com/tc39/proposal-intl-segmenter
 */
export const REGEX_TAB_OR_SURROGATE_PAIR = /\t|[\uD800-\uDBFF][\uDC00-\uDFFF]/;

export function getResponsiveMode(
  prefs?: DiffPreferencesInfo,
  renderPrefs?: RenderPreferences
): DiffResponsiveMode {
  if (renderPrefs?.responsive_mode) {
    return renderPrefs.responsive_mode;
  }
  // Backwards compatibility to the line_wrapping param.
  if (prefs?.line_wrapping) {
    return 'FULL_RESPONSIVE';
  }
  return 'NONE';
}

export function isResponsive(responsiveMode?: DiffResponsiveMode) {
  return (
    responsiveMode === 'FULL_RESPONSIVE' || responsiveMode === 'SHRINK_ONLY'
  );
}

/**
 * Compare two ranges. Either argument may be falsy, but will only return
 * true if both are falsy or if neither are falsy and have the same position
 * values.
 */
export function rangesEqual(a?: CommentRange, b?: CommentRange): boolean {
  if (!a && !b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  return (
    a.start_line === b.start_line &&
    a.start_character === b.start_character &&
    a.end_line === b.end_line &&
    a.end_character === b.end_character
  );
}

export function isLongCommentRange(range: CommentRange): boolean {
  return range.end_line - range.start_line > 10;
}

export function getLineNumberByChild(node?: Node) {
  return getLineNumber(getLineElByChild(node));
}

export function lineNumberToNumber(lineNumber?: LineNumber | null): number {
  if (typeof lineNumber !== 'number') return 0;
  return lineNumber;
}

export function getLineElByChild(node?: Node): HTMLElement | null {
  while (node) {
    if (node instanceof Element) {
      if (node.classList.contains('lineNum')) {
        return node as HTMLElement;
      }
      if (node.classList.contains('section')) {
        return null;
      }
    }
    node =
      (node as Element).assignedSlot ??
      (node as ShadowRoot).host ??
      node.previousSibling ??
      node.parentNode ??
      undefined;
  }
  return null;
}

export function getSideByLineEl(lineEl: Element) {
  return lineEl.classList.contains(Side.RIGHT) ? Side.RIGHT : Side.LEFT;
}

export function getLineNumber(lineEl?: Element | null): LineNumber | null {
  if (!lineEl) return null;
  const lineNumberStr = lineEl.getAttribute('data-value');
  if (!lineNumberStr) return null;
  if (lineNumberStr === FILE) return FILE;
  if (lineNumberStr === LOST) return LOST;
  const lineNumber = Number(lineNumberStr);
  return Number.isInteger(lineNumber) ? lineNumber : null;
}

export function getLine(threadEl: HTMLElement): LineNumber {
  const lineAtt = threadEl.getAttribute('line-num');
  if (lineAtt === LOST) return lineAtt;
  if (!lineAtt || lineAtt === FILE) return FILE;
  const line = Number(lineAtt);
  if (isNaN(line)) throw new Error(`cannot parse line number: ${lineAtt}`);
  if (line < 1) throw new Error(`line number smaller than 1: ${line}`);
  return line;
}

export function getSide(threadEl: HTMLElement): Side | undefined {
  const sideAtt = threadEl.getAttribute('diff-side');
  if (!sideAtt) {
    console.warn('comment thread without side');
    return undefined;
  }
  if (sideAtt !== Side.LEFT && sideAtt !== Side.RIGHT)
    throw Error(`unexpected value for side: ${sideAtt}`);
  return sideAtt as Side;
}

export function getRange(threadEl: HTMLElement): CommentRange | undefined {
  const rangeAtt = threadEl.getAttribute('range');
  if (!rangeAtt) return undefined;
  const range = JSON.parse(rangeAtt) as CommentRange;
  if (!range.start_line) return undefined;
  return range;
}

/**
 * This is all the data that gr-diff extracts from comment thread elements,
 * see `GrDiffThreadElement`. Otherwise gr-diff treats such elements as a black
 * box.
 */
export interface GrDiffCommentThread {
  side: Side;
  line: LineNumber;
  range?: CommentRange;
  rootId?: string;
}

/**
 * Retrieves all the data from a comment thread element that the gr-diff API
 * contract defines for such elements.
 */
export function getDataFromCommentThreadEl(
  threadEl?: EventTarget | null
): GrDiffCommentThread | undefined {
  if (!isThreadEl(threadEl)) return undefined;
  const side = getSide(threadEl);
  const line = getLine(threadEl);
  const range = getRange(threadEl);
  if (!side) return undefined;
  if (!line) return undefined;
  return {side, line, range, rootId: threadEl.rootId};
}

export interface KeyLocations {
  left: {[key: string]: boolean};
  right: {[key: string]: boolean};
}

/**
 * "Context" is the number of lines that we are showing around diff chunks and
 * commented lines. This typically comes from a user preference and is set to
 * something like 3 or 10.
 *
 * `FULL_CONTEXT` means that the user wants to see the entire file. We could
 * also call this "infinite context".
 */
export const FULL_CONTEXT = -1;

export enum FullContext {
  /** User has opted into showing the full context. */
  YES = 'YES',
  /** User has opted into showing only limited context. */
  NO = 'NO',
  /**
   * User has not decided yet. Will see a warning message with two options then,
   * if the file is too large.
   */
  UNDECIDED = 'UNDECIDED',
}

export function computeContext(
  prefsContext: number | undefined,
  showFullContext: FullContext,
  defaultContext: number
) {
  if (showFullContext === FullContext.YES) {
    return FULL_CONTEXT;
  }
  if (
    prefsContext !== undefined &&
    !(showFullContext === FullContext.NO && prefsContext === FULL_CONTEXT)
  ) {
    return prefsContext;
  }
  return defaultContext;
}

export function computeLineLength(
  prefs: DiffPreferencesInfo,
  path: string | undefined
): number {
  if (path === SpecialFilePath.COMMIT_MESSAGE) {
    return 72;
  }
  const lineLength = prefs.line_length;
  if (Number.isInteger(lineLength) && lineLength > 0) {
    return lineLength;
  }
  return 100;
}

export function computeKeyLocations(
  lineOfInterest: DisplayLine | undefined,
  comments: GrDiffCommentThread[]
) {
  const keyLocations: KeyLocations = {left: {}, right: {}};

  if (lineOfInterest) {
    keyLocations[lineOfInterest.side][lineOfInterest.lineNum] = true;
  }

  for (const comment of comments) {
    keyLocations[comment.side][comment.line] = true;
    if (comment.range?.start_line) {
      keyLocations[comment.side][comment.range.start_line] = true;
    }
  }

  return keyLocations;
}

export function compareComments(
  c1: GrDiffCommentThread,
  c2: GrDiffCommentThread
): number {
  if (c1.side !== c2.side) {
    return c1.side === Side.RIGHT ? 1 : -1;
  }

  if (c1.line !== c2.line) {
    if (c1.line === FILE && c2.line !== FILE) return -1;
    if (c1.line !== FILE && c2.line === FILE) return 1;
    if (c1.line === LOST && c2.line !== LOST) return -1;
    if (c1.line !== LOST && c2.line === LOST) return 1;
    return (c1.line as number) - (c2.line as number);
  }

  if (c1.rootId !== c2.rootId) {
    if (!c1.rootId) return -1;
    if (!c2.rootId) return 1;
    return c1.rootId > c2.rootId ? 1 : -1;
  }

  if (c1.range && c2.range) {
    const r1 = JSON.stringify(c1.range);
    const r2 = JSON.stringify(c2.range);
    return r1 > r2 ? 1 : -1;
  }
  if (c1.range) return 1;
  if (c2.range) return -1;

  return 0;
}

// TODO: This type should be exposed to gr-diff clients in a separate type file.
// For Gerrit these are instances of GrCommentThread, but other gr-diff users
// have different HTML elements in use for comment threads.
// TODO: Also document the required HTML attributes that thread elements must
// have, e.g. 'diff-side', 'range' (optional), 'line-num'.
// Comment widgets are also required to have `comment-thread` in their css
// class list.
export interface GrDiffThreadElement extends HTMLElement {
  rootId: string;
}

export function isThreadEl(
  node?: Node | EventTarget | null
): node is GrDiffThreadElement {
  return (
    !!node &&
    (node as Node).nodeType === Node.ELEMENT_NODE &&
    (node as Element).classList.contains('comment-thread')
  );
}

/**
 * Simple helper method for creating element classes in the context of
 * gr-diff. This is just a super simple convenience function.
 */
export function diffClasses(...additionalClasses: string[]) {
  return ['gr-diff', ...additionalClasses].join(' ');
}

/**
 * Simple helper method for creating elements in the context of gr-diff.
 * This is just a super simple convenience function.
 */
export function createElementDiff(
  tagName: string,
  classStr?: string
): HTMLElement {
  const el = document.createElement(tagName);

  el.classList.add('gr-diff');
  if (classStr) {
    for (const className of classStr.split(' ')) {
      el.classList.add(className);
    }
  }
  return el;
}

export function createElementDiffWithText(
  tagName: string,
  textContent: string
) {
  const element = createElementDiff(tagName);
  element.textContent = textContent;
  return element;
}

export function createLineBreak(mode: DiffResponsiveMode) {
  return isResponsive(mode)
    ? createElementDiff('wbr')
    : createElementDiff('span', 'br');
}

/**
 * Returns a <span> element holding a '\t' character, that will visually
 * occupy |tabSize| many columns.
 *
 * @param tabSize The effective size of this tab stop.
 */
export function createTabWrapper(tabSize: number): HTMLElement {
  // Force this to be a number to prevent arbitrary injection.
  const result = createElementDiff('span', 'tab');
  result.setAttribute(
    'style',
    `tab-size: ${tabSize}; -moz-tab-size: ${tabSize};`
  );
  result.innerText = '\t';
  return result;
}

/**
 * Returns a 'div' element containing the supplied |text| as its innerText,
 * with '\t' characters expanded to a width determined by |tabSize|, and the
 * text wrapped at column |lineLimit|, which may be Infinity if no wrapping is
 * desired.
 *
 * @param text The text to be formatted.
 * @param responsiveMode The responsive mode of the diff.
 * @param tabSize The width of each tab stop.
 * @param lineLimit The column after which to wrap lines.
 */
export function formatText(
  text: string,
  responsiveMode: DiffResponsiveMode,
  tabSize: number,
  lineLimit: number,
  elementId: string
): HTMLElement {
  const contentText = createElementDiff('div', 'contentText');
  // <gr-legacy-text> is not defined anywhere, so this behave just as a <div>
  // would. We use this during the migration to lit based diff elements to
  // match <gr-diff-text>. We define a css rule with `display:contents` making
  // sure that this extra element is basically a no-op.
  const legacyText = document.createElement('gr-legacy-text');
  contentText.appendChild(legacyText);
  contentText.id = elementId;
  let columnPos = 0;
  let textOffset = 0;
  for (const segment of text.split(REGEX_TAB_OR_SURROGATE_PAIR)) {
    if (segment) {
      // |segment| contains only normal characters. If |segment| doesn't fit
      // entirely on the current line, append chunks of |segment| followed by
      // line breaks.
      let rowStart = 0;
      let rowEnd = lineLimit - columnPos;
      while (rowEnd < segment.length) {
        legacyText.appendChild(
          document.createTextNode(segment.substring(rowStart, rowEnd))
        );
        legacyText.appendChild(createLineBreak(responsiveMode));
        columnPos = 0;
        rowStart = rowEnd;
        rowEnd += lineLimit;
      }
      // Append the last part of |segment|, which fits on the current line.
      legacyText.appendChild(
        document.createTextNode(segment.substring(rowStart))
      );
      columnPos += segment.length - rowStart;
      textOffset += segment.length;
    }
    if (textOffset < text.length) {
      // Handle the special character at |textOffset|.
      if (text.startsWith('\t', textOffset)) {
        // Append a single '\t' character.
        let effectiveTabSize = tabSize - (columnPos % tabSize);
        if (columnPos + effectiveTabSize > lineLimit) {
          legacyText.appendChild(createLineBreak(responsiveMode));
          columnPos = 0;
          effectiveTabSize = tabSize;
        }
        legacyText.appendChild(createTabWrapper(effectiveTabSize));
        columnPos += effectiveTabSize;
        textOffset++;
      } else {
        // Append a single surrogate pair.
        if (columnPos >= lineLimit) {
          legacyText.appendChild(createLineBreak(responsiveMode));
          columnPos = 0;
        }
        legacyText.appendChild(
          document.createTextNode(text.substring(textOffset, textOffset + 2))
        );
        textOffset += 2;
        columnPos += 1;
      }
    }
  }
  return contentText;
}

export interface DiffContextExpandedEventDetail
  extends DiffContextExpandedExternalDetail {
  /** The context control group that should be replaced by `groups`. */
  contextGroup: GrDiffGroup;
  groups: GrDiffGroup[];
  numLines: number;
}
