// Copyright 2019 The Chromium Authors
// 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';
import {generateProjectIssueURL} from 'shared/helpers.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) {
  const params = {'id': localId};
  const href = generateProjectIssueURL(projectName, '/detail', params)
  return {
    tag: 'a',
    css: isClosed ? 'strike-through' : '',
    href: href + 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};
