// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';
import {prpcClient} from 'prpc-client-instance.js';

/* eslint-disable max-len */
// When crbug links don't specify a project, the default project is Chromium.
const CRBUG_DEFAULT_PROJECT = 'chromium';
const CRBUG_LINK_RE = /(\b(https?:\/\/)?crbug\.com\/)((\b[-a-z0-9]+)(\/))?(\d+)\b(\#c[0-9]+)?/gi;
const CRBUG_LINK_RE_PROJECT_GROUP = 4;
const CRBUG_LINK_RE_ID_GROUP = 6;
const CRBUG_LINK_RE_COMMENT_GROUP = 7;
const ISSUE_TRACKER_RE = /(\b(issues?|bugs?)[ \t]*(:|=|\b)|\bfixed[ \t]*:)([ \t]*((\b[-a-z0-9]+)[:\#])?(\#?)(\d+)\b(,?[ \t]*(and|or)?)?)+/gi;
const PROJECT_LOCALID_RE = /((\b(issue|bug)[ \t]*(:|=)?[ \t]*|\bfixed[ \t]*:[ \t]*)?((\b[-a-z0-9]+)[:\#])?(\#?)(\d+))/gi;
const PROJECT_COMMENT_BUG_RE = /(((\b(issue|bug)[ \t]*(:|=)?[ \t]*)(\#?)(\d+)[ \t*])?((\b((comment)[ \t]*(:|=)?[ \t]*(\#?))|(\B((\#))(c)))(\d+)))/gi;
const PROJECT_LOCALID_RE_PROJECT_GROUP = 6;
const PROJECT_LOCALID_RE_ID_GROUP = 8;
const IMPLIED_EMAIL_RE = /\b[a-z]((-|\.)?[a-z0-9])+@[a-z]((-|\.)?[a-z0-9])+\.(com|net|org|edu|dev)\b/gi;
// TODO(zhangtiff): Replace (^|[^-/._]) with (?<![-/._]) on the 3 Regexes below
// once Firefox supports lookaheads.
const SHORT_LINK_RE = /(^|[^-\/._])\b(https?:\/\/|ftp:\/\/|mailto:)?(go|g|shortn|who|teams)\/([^\s<]+)/gi;
const NUMERIC_SHORT_LINK_RE = /(^|[^-\/._])\b(https?:\/\/|ftp:\/\/)?(b|t|o|omg|cl|cr|fxr|fxrev|fxb|tqr)\/([0-9]+)/gi;
const IMPLIED_LINK_RE = /(^|[^-\/._])\b[a-z]((-|\.)?[a-z0-9])+\.(com|net|org|edu|dev)\b(\/[^\s<]*)?/gi;
const IS_LINK_RE = /()\b(https?:\/\/|ftp:\/\/|mailto:)([^\s<]+)/gi;
const GIT_HASH_RE = /\b(r(evision\s+#?)?)?([a-f0-9]{40})\b/gi;
const SVN_REF_RE = /\b(r(evision\s+#?)?)([0-9]{4,7})\b/gi;
const NEW_LINE_REGEX = /^(\r\n?|\n)$/;
const NEW_LINE_OR_BOLD_REGEX = /(<b>[^<\n]+<\/b>)|(\r\n?|\n)/;
// The revNum is in the same position for the above two Regexes. The
// extraction function uses this similar format to allow switching out
// Regexes easily, so be careful about changing GIT_HASH_RE and SVN_HASH_RE.
const REV_NUM_GROUP = 3;
const LINK_TRAILING_CHARS = [
  [null, ':'],
  [null, '.'],
  [null, ','],
  [null, '>'],
  ['(', ')'],
  ['[', ']'],
  ['{', '}'],
  ['\'', '\''],
  ['"', '"'],
];
const GOOG_SHORT_LINK_RE = /^(b|t|o|omg|cl|cr|go|g|shortn|who|teams|fxr|fxrev|fxb|tqr)\/.*/gi;
/* eslint-enable max-len */

const Components = new Map();
// TODO(zosha): Combine functions of Component 00 with 01 so that
// user can only reference valid issues in the issue/comment linking.
// Allow user to reference multiple comments on the same issue.
// Additionally, allow for the user to reference this on a specific project.
// Note: the order of the components is important for proper autolinking.
Components.set(
    '00-commentbug',
    {
      lookup: null,
      extractRefs: null,
      refRegs: [PROJECT_COMMENT_BUG_RE],
      replacer: ReplaceCommentBugRef,
    },
);
Components.set(
    '01-tracker-crbug',
    {
      lookup: LookupReferencedIssues,
      extractRefs: ExtractCrbugProjectAndIssueIds,
      refRegs: [CRBUG_LINK_RE],
      replacer: ReplaceCrbugIssueRef,

    },
);
Components.set(
    '02-full-urls',
    {
      lookup: null,
      extractRefs: (match, _currentProjectName) => {
        return [match[0]];
      },
      refRegs: [IS_LINK_RE],
      replacer: ReplaceLinkRef,
    },
);
Components.set(
    '03-user-emails',
    {
      lookup: LookupReferencedUsers,
      extractRefs: (match, _currentProjectName) => {
        return [match[0]];
      },
      refRegs: [IMPLIED_EMAIL_RE],
      replacer: ReplaceUserRef,
    },
);
Components.set(
    '04-tracker-regular',
    {
      lookup: LookupReferencedIssues,
      extractRefs: ExtractTrackerProjectAndIssueIds,
      refRegs: [ISSUE_TRACKER_RE],
      replacer: ReplaceTrackerIssueRef,
    },
);
Components.set(
    '05-linkify-shorthand',
    {
      lookup: null,
      extractRefs: (match, _currentProjectName) => {
        return [match[0]];
      },
      refRegs: [
        SHORT_LINK_RE,
        NUMERIC_SHORT_LINK_RE,
        IMPLIED_LINK_RE,
      ],
      replacer: ReplaceLinkRef,
    },
);
Components.set(
    '06-versioncontrol',
    {
      lookup: null,
      extractRefs: (match, _currentProjectName) => {
        return [match[0]];
      },
      refRegs: [GIT_HASH_RE, SVN_REF_RE],
      replacer: ReplaceRevisionRef,
    },
);

// Lookup referenced artifacts functions.
function LookupReferencedIssues(issueRefs, componentName) {
  return new Promise((resolve, reject) => {
    issueRefs = issueRefs.filter(
        ({projectName, localId}) => projectName && parseInt(localId));
    const listReferencedIssues = prpcClient.call(
        'monorail.Issues', 'ListReferencedIssues', {issueRefs});
    return listReferencedIssues.then((response) => {
      resolve({'componentName': componentName, 'existingRefs': response});
    });
  });
}

function LookupReferencedUsers(emails, componentName) {
  return new Promise((resolve, reject) => {
    const userRefs = emails.map((displayName) => {
      return {displayName};
    });
    const listReferencedUsers = prpcClient.call(
        'monorail.Users', 'ListReferencedUsers', {userRefs});
    return listReferencedUsers.then((response) => {
      resolve({'componentName': componentName, 'existingRefs': response});
    });
  });
}

// Extract referenced artifacts info functions.
function ExtractCrbugProjectAndIssueIds(match, _currentProjectName) {
  // When crbug links don't specify a project, the default project is Chromium.
  const projectName = match[CRBUG_LINK_RE_PROJECT_GROUP] ||
    CRBUG_DEFAULT_PROJECT;
  const localId = match[CRBUG_LINK_RE_ID_GROUP];
  return [{projectName: projectName, localId: localId}];
}

function ExtractTrackerProjectAndIssueIds(match, currentProjectName) {
  const issueRefRE = PROJECT_LOCALID_RE;
  let refMatch;
  const refs = [];
  while ((refMatch = issueRefRE.exec(match[0])) !== null) {
    if (refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP]) {
      currentProjectName = refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP];
    }
    refs.push({
      projectName: currentProjectName,
      localId: refMatch[PROJECT_LOCALID_RE_ID_GROUP],
    });
  }
  return refs;
}

// Replace plain text references with links functions.
function ReplaceIssueRef(stringMatch, projectName, localId, components,
    commentId) {
  if (components.openRefs && components.openRefs.length) {
    const openRef = components.openRefs.find((ref) => {
      return ref.localId && ref.projectName && (ref.localId == localId) &&
          (ref.projectName.toLowerCase() === projectName.toLowerCase());
    });
    if (openRef) {
      return createIssueRefRun(
          projectName, localId, openRef.summary, false, stringMatch, commentId);
    }
  }
  if (components.closedRefs && components.closedRefs.length) {
    const closedRef = components.closedRefs.find((ref) => {
      return ref.localId && ref.projectName && (ref.localId == localId) &&
          (ref.projectName.toLowerCase() === projectName.toLowerCase());
    });
    if (closedRef) {
      return createIssueRefRun(
          projectName, localId, closedRef.summary, true, stringMatch,
          commentId);
    }
  }
  return {content: stringMatch};
}

function ReplaceCrbugIssueRef(match, components, _currentProjectName) {
  components = components || {};
  // When crbug links don't specify a project, the default project is Chromium.
  const projectName =
    match[CRBUG_LINK_RE_PROJECT_GROUP] || CRBUG_DEFAULT_PROJECT;
  const localId = match[CRBUG_LINK_RE_ID_GROUP];
  let commentId = '';
  if (match[CRBUG_LINK_RE_COMMENT_GROUP] !== undefined) {
    commentId = match[CRBUG_LINK_RE_COMMENT_GROUP];
  }
  return [ReplaceIssueRef(match[0], projectName, localId, components,
      commentId)];
}

function ReplaceTrackerIssueRef(match, components, currentProjectName) {
  components = components || {};
  const issueRefRE = PROJECT_LOCALID_RE;
  const commentId = '';
  const textRuns = [];
  let refMatch;
  let pos = 0;
  while ((refMatch = issueRefRE.exec(match[0])) !== null) {
    if (refMatch.index > pos) {
      // Create textrun for content between previous and current match.
      textRuns.push({content: match[0].slice(pos, refMatch.index)});
    }
    if (refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP]) {
      currentProjectName = refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP];
    }
    textRuns.push(ReplaceIssueRef(
        refMatch[0], currentProjectName,
        refMatch[PROJECT_LOCALID_RE_ID_GROUP], components, commentId));
    pos = refMatch.index + refMatch[0].length;
  }
  if (match[0].slice(pos) !== '') {
    textRuns.push({content: match[0].slice(pos)});
  }
  return textRuns;
}

function ReplaceUserRef(match, components, _currentProjectName) {
  components = components || {};
  const textRun = {content: match[0], tag: 'a'};
  if (components.users && components.users.length) {
    const existingUser = components.users.find((user) => {
      return user.displayName.toLowerCase() === match[0].toLowerCase();
    });
    if (existingUser) {
      textRun.href = `/u/${match[0]}`;
      return [textRun];
    }
  }
  textRun.href = `mailto:${match[0]}`;
  return [textRun];
}

function ReplaceCommentBugRef(match) {
  let textRun;
  const issueNum = match[7];
  const commentNum = match[18];
  if (issueNum && commentNum) {
    textRun = {content: match[0], tag: 'a', href: `?id=${issueNum}#c${commentNum}`};
  } else if (commentNum) {
    textRun = {content: match[0], tag: 'a', href: `#c${commentNum}`};
  } else {
    textRun = {content: match[0]};
  }
  return [textRun];
}

function ReplaceLinkRef(match, _components, _currentProjectName) {
  const textRuns = [];
  let content = match[0];
  let trailing = '';
  if (match[1]) {
    textRuns.push({content: match[1]});
    content = content.slice(match[1].length);
  }
  LINK_TRAILING_CHARS.forEach(([begin, end]) => {
    if (content.endsWith(end)) {
      if (!begin || !content.slice(0, -end.length).includes(begin)) {
        trailing = end + trailing;
        content = content.slice(0, -end.length);
      }
    }
  });
  let href = content;
  const lowerHref = href.toLowerCase();
  if (!lowerHref.startsWith('http') && !lowerHref.startsWith('ftp') &&
      !lowerHref.startsWith('mailto')) {
    // Prepend google-internal short links with http to
    // prevent HTTPS error interstitial.
    // SHORT_LINK_RE should not be used here as it might be
    // in the middle of another match() process in an outer loop.
    if (GOOG_SHORT_LINK_RE.test(lowerHref)) {
      href = 'http://' + href;
    } else {
      href = 'https://' + href;
    }
    GOOG_SHORT_LINK_RE.lastIndex = 0;
  }
  textRuns.push({content: content, tag: 'a', href: href});
  if (trailing.length) {
    textRuns.push({content: trailing});
  }
  return textRuns;
}

function ReplaceRevisionRef(
    match, _components, _currentProjectName, revisionUrlFormat) {
  const content = match[0];
  const href = revisionUrlFormat.replace('{revnum}', match[REV_NUM_GROUP]);
  return [{content: content, tag: 'a', href: href}];
}

// Create custom textrun functions.
function createIssueRefRun(projectName, localId, summary, isClosed, content,
    commentId) {
  return {
    tag: 'a',
    css: isClosed ? 'strike-through' : '',
    href: `/p/${projectName}/issues/detail?id=${localId}${commentId}`,
    title: summary || '',
    content: content,
  };
}

/**
 * @typedef {Object} CommentReference
 * @property {string} componentName A key identifying the kind of autolinking
 *   text the reference matches.
 * @property {Array<any>} existingRefs Array of full data for referenced
 *   Objects. Each entry in this Array could be any kind of data depending
 *   on what the text references. For example, the Array could contain Issue
 *   or User Objects.
 */

/**
 * Iterates through a list of comments, requests data for referenced objects
 * in those comments, and returns all fetched data.
 * @param {Array<IssueComment>} comments Array of comments to check.
 * @param {string} currentProjectName Project these comments exist in the
 *   context of.
 * @return {Promise<Array<CommentReference>>}
 */
function getReferencedArtifacts(comments, currentProjectName) {
  return new Promise((resolve, reject) => {
    const fetchPromises = [];
    Components.forEach(({lookup, extractRefs, refRegs}, componentName) => {
      if (lookup !== null) {
        const refs = [];
        refRegs.forEach((re) => {
          let match;
          comments.forEach((comment) => {
            while ((match = re.exec(comment.content)) !== null) {
              refs.push(...extractRefs(match, currentProjectName));
            };
          });
        });
        if (refs.length) {
          fetchPromises.push(lookup(refs, componentName));
        }
      }
    });
    resolve(Promise.all(fetchPromises));
  });
}

function markupAutolinks(
    plainString, componentRefs, currentProjectName, revisionUrlFormat) {
  plainString = plainString || '';
  const chunks = plainString.trim().split(NEW_LINE_OR_BOLD_REGEX);
  const textRuns = [];
  chunks.filter(Boolean).forEach((chunk) => {
    if (chunk.match(NEW_LINE_REGEX)) {
      textRuns.push({tag: 'br'});
    } else if (chunk.startsWith('<b>') && chunk.endsWith('</b>')) {
      textRuns.push({content: chunk.slice(3, -4), tag: 'b'});
    } else {
      textRuns.push(
          ...autolinkChunk(
              chunk, componentRefs, currentProjectName, revisionUrlFormat));
    }
  });
  return textRuns;
}

function autolinkChunk(
    chunk, componentRefs, currentProjectName, revisionUrlFormat) {
  let textRuns = [{content: chunk}];
  Components.forEach(({refRegs, replacer}, componentName) => {
    refRegs.forEach((re) => {
      textRuns = applyLinks(
          textRuns, replacer, re, componentRefs.get(componentName),
          currentProjectName, revisionUrlFormat);
    });
  });
  return textRuns;
}

function applyLinks(
    textRuns, replacer, re, existingRefs, currentProjectName,
    revisionUrlFormat) {
  const resultRuns = [];
  textRuns.forEach((textRun) => {
    if (textRun.tag) {
      resultRuns.push(textRun);
    } else {
      const content = textRun.content;
      let pos = 0;
      let match;
      while ((match = re.exec(content)) !== null) {
        if (match.index > pos) {
          // Create textrun for content between previous and current match.
          resultRuns.push({content: content.slice(pos, match.index)});
        }
        resultRuns.push(
            ...replacer(
                match, existingRefs, currentProjectName, revisionUrlFormat));
        pos = match.index + match[0].length;
      }
      if (content.slice(pos) !== '') {
        resultRuns.push({content: content.slice(pos)});
      }
    }
  });
  return resultRuns;
}


export const autolink = {Components, getReferencedArtifacts, markupAutolinks};
