/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
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 rewriteResults = getRewriteResultsFromConfig(base, repoCommentLinks);
  return applyRewrites(base, rewriteResults);
}

/**
 * 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)
  );
  // Always linkify URLs starting with https?://
  enabledRewrites.push({
    match: '(https?://((?!&(gt|lt|amp|quot|apos);)\\S)+[\\w/~-])',
    link: '$1',
  });
  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');
  }
}

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