/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import 'ba-linkify/ba-linkify';
import {CommentLinkInfo, CommentLinks} from '../types/common';
import {getBaseUrl} from './url-util';

/**
 * Finds links within the base string and convert them to HTML. Config-based
 * rewrites are only applied on text that is not linked by the default linking
 * library.
 */
export function linkifyUrlsAndApplyRewrite(
  base: string,
  repoCommentLinks: CommentLinks
): string {
  const parts: string[] = [];
  window.linkify(insertZeroWidthSpace(base), {
    callback: (text, href) => {
      if (href) {
        parts.push(removeZeroWidthSpace(createLinkTemplate(href, text)));
      } else {
        const rewriteResults = getRewriteResultsFromConfig(
          text,
          repoCommentLinks
        );
        parts.push(removeZeroWidthSpace(applyRewrites(text, rewriteResults)));
      }
    },
  });
  return parts.join('');
}

/**
 * Generates a list of rewrites that would be applied to a base string. They are
 * not applied immediately to the base text because one rewrite may interfere or
 * overlap with a later rewrite. Only after all rewrites are known they are
 * carefully merged with `applyRewrites`.
 */
function getRewriteResultsFromConfig(
  base: string,
  repoCommentLinks: CommentLinks
): RewriteResult[] {
  const enabledRewrites = Object.values(repoCommentLinks).filter(
    commentLinkInfo =>
      commentLinkInfo.enabled !== false &&
      (commentLinkInfo.link !== undefined || commentLinkInfo.html !== undefined)
  );
  return enabledRewrites.flatMap(rewrite => {
    const regexp = new RegExp(rewrite.match, 'g');
    const partialResults: RewriteResult[] = [];
    let match: RegExpExecArray | null;

    while ((match = regexp.exec(base)) !== null) {
      const fullReplacementText = getReplacementText(match[0], rewrite);
      // The replacement may not be changing the entire matched substring so we
      // "trim" the replacement position and text to the part that is actually
      // different. This makes sure that unchanged portions are still eligible
      // for other rewrites without being rejected as overlaps during
      // `applyRewrites`. The new `replacementText` is not eligible for other
      // rewrites since it would introduce unexpected interactions between
      // rewrites depending on their order of definition/execution.
      const sharedPrefixLength = getSharedPrefixLength(
        match[0],
        fullReplacementText
      );
      const sharedSuffixLength = getSharedSuffixLength(
        match[0],
        fullReplacementText
      );
      const prefixIndex = sharedPrefixLength;
      const matchSuffixIndex = match[0].length - sharedSuffixLength;
      const fullReplacementSuffixIndex =
        fullReplacementText.length - sharedSuffixLength;
      partialResults.push({
        replacedTextStartPosition: match.index + prefixIndex,
        replacedTextEndPosition: match.index + matchSuffixIndex,
        replacementText: fullReplacementText.substring(
          prefixIndex,
          fullReplacementSuffixIndex
        ),
      });
    }
    return partialResults;
  });
}

/**
 * Applies all the rewrites to the given base string. To resolve cases where
 * multiple rewrites target overlapping pieces of the base string, the rewrite
 * that ends latest is kept and the rest are not applied and discarded.
 */
function applyRewrites(base: string, rewriteResults: RewriteResult[]): string {
  const rewritesByEndPosition = [...rewriteResults].sort((a, b) => {
    if (b.replacedTextEndPosition !== a.replacedTextEndPosition) {
      return b.replacedTextEndPosition - a.replacedTextEndPosition;
    }
    return a.replacedTextStartPosition - b.replacedTextStartPosition;
  });
  const filteredSortedRewrites: RewriteResult[] = [];
  let latestReplace = base.length;
  for (const rewrite of rewritesByEndPosition) {
    // Only accept rewrites that do not overlap with any previously accepted
    // rewrites.
    if (rewrite.replacedTextEndPosition <= latestReplace) {
      filteredSortedRewrites.push(rewrite);
      latestReplace = rewrite.replacedTextStartPosition;
    }
  }
  return filteredSortedRewrites.reduce(
    (text, rewrite) =>
      text
        .substring(0, rewrite.replacedTextStartPosition)
        .concat(rewrite.replacementText)
        .concat(text.substring(rewrite.replacedTextEndPosition)),
    base
  );
}

/**
 * For a given regexp match, apply the rewrite based on the rewrite's type and
 * return the resulting string.
 */
function getReplacementText(
  matchedText: string,
  rewrite: CommentLinkInfo
): string {
  if (rewrite.link !== undefined) {
    const replacementHref = rewrite.link.startsWith('/')
      ? `${getBaseUrl()}${rewrite.link}`
      : rewrite.link;
    const regexp = new RegExp(rewrite.match, 'g');
    return matchedText.replace(
      regexp,
      createLinkTemplate(
        replacementHref,
        rewrite.text ?? '$&',
        rewrite.prefix,
        rewrite.suffix
      )
    );
  } else if (rewrite.html !== undefined) {
    return matchedText.replace(new RegExp(rewrite.match, 'g'), rewrite.html);
  } else {
    throw new Error('commentLinkInfo is not a link or html rewrite');
  }
}

/**
 * Some tools are known to look for reviewers/CCs by finding lines such as
 * "R=foo@gmail.com, bar@gmail.com". However, "=" is technically a valid email
 * character, so ba-linkify interprets the entire string "R=foo@gmail.com" as an
 * email address. To fix this, we insert a zero width space character \u200B
 * before linking that prevents ba-linkify from associating the prefix with the
 * email. After linking we remove the zero width space.
 */
function insertZeroWidthSpace(base: string) {
  return base.replace(/^(R=|CC=)/g, '$&\u200B');
}

function removeZeroWidthSpace(base: string) {
  return base.replace(/\u200B/g, '');
}

function createLinkTemplate(
  href: string,
  displayText: string,
  prefix?: string,
  suffix?: string
) {
  return `${
    prefix ?? ''
  }<a href="${href}" rel="noopener" target="_blank">${displayText}</a>${
    suffix ?? ''
  }`;
}

/**
 * Returns the number of characters that are identical at the start of both
 * strings.
 *
 * For example, `getSharedPrefixLength('12345678', '1234zz78')` would return 4
 */
function getSharedPrefixLength(a: string, b: string) {
  let i = 0;
  for (; i < a.length && i < b.length; ++i) {
    if (a[i] !== b[i]) {
      return i;
    }
  }
  return i;
}

/**
 * Returns the number of characters that are identical at the end of both
 * strings.
 *
 * For example, `getSharedSuffixLength('12345678', '1234zz78')` would return 2
 */
function getSharedSuffixLength(a: string, b: string) {
  let i = a.length;
  for (let j = b.length; i !== 0 && j !== 0; --i, --j) {
    if (a[i] !== b[j]) {
      return a.length - 1 - i;
    }
  }
  return a.length - i;
}

interface RewriteResult {
  replacedTextStartPosition: number;
  replacedTextEndPosition: number;
  replacementText: string;
}
