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

function createLinkTemplate(
  href: string,
  displayText: string,
  prefix?: string,
  suffix?: string
) {
  return `${
    prefix ?? ''
  }<a href="${href}" rel="noopener noreferrer" 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;
}
