/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  CommentBasics,
  CommentInfo,
  PatchSetNum,
  RobotCommentInfo,
  Timestamp,
  UrlEncodedCommentId,
  CommentRange,
  PatchRange,
  PARENT,
  ContextLine,
  BasePatchSetNum,
  RevisionPatchSetNum,
  AccountInfo,
  AccountDetailInfo,
  ChangeMessageInfo,
  VotingRangeInfo,
  FixSuggestionInfo,
  FixId,
  PatchSetNumber,
} from '../types/common';
import {CommentSide, SpecialFilePath} from '../constants/constants';
import {parseDate} from './date-util';
import {CommentIdToCommentThreadMap} from '../elements/diff/gr-comment-api/gr-comment-api';
import {isMergeParent, getParentIndex} from './patch-set-util';
import {DiffInfo} from '../types/diff';
import {LineNumber} from '../api/diff';
import {FormattedReviewerUpdateInfo} from '../types/types';
import {extractMentionedUsers} from './account-util';

export interface DraftCommentProps {
  // This must be true for all drafts. Drafts received from the backend will be
  // modified immediately with __draft:true before allowing them to get into
  // the application state.
  __draft: boolean;
}

export interface UnsavedCommentProps {
  // This must be true for all unsaved comment drafts. An unsaved draft is
  // always just local to a comment component like <gr-comment> or
  // <gr-comment-thread>. Unsaved drafts will never appear in the application
  // state.
  __unsaved: boolean;
}

export type DraftInfo = CommentInfo & DraftCommentProps;

export type UnsavedInfo = CommentBasics & UnsavedCommentProps;

export type Comment = UnsavedInfo | DraftInfo | CommentInfo | RobotCommentInfo;

// TODO: Replace the CommentMap type with just an array of paths.
export type CommentMap = {[path: string]: boolean};

export function isRobot<T extends CommentBasics>(
  x: T | DraftInfo | RobotCommentInfo | undefined
): x is RobotCommentInfo {
  return !!x && !!(x as RobotCommentInfo).robot_id;
}

export function isDraft<T extends CommentBasics>(
  x: T | DraftInfo | undefined
): x is DraftInfo {
  return !!x && !!(x as DraftInfo).__draft;
}

export function isUnsaved<T extends CommentBasics>(
  x: T | UnsavedInfo | undefined
): x is UnsavedInfo {
  return !!x && !!(x as UnsavedInfo).__unsaved;
}

export function isDraftOrUnsaved<T extends CommentBasics>(
  x: T | DraftInfo | UnsavedInfo | undefined
): x is UnsavedInfo | DraftInfo {
  return isDraft(x) || isUnsaved(x);
}

interface SortableComment {
  updated: Timestamp;
  id: UrlEncodedCommentId;
}

export interface ChangeMessage extends ChangeMessageInfo {
  // TODO(TS): maybe should be an enum instead
  type: string;
  expanded: boolean;
  commentThreads: CommentThread[];
}

export function isFormattedReviewerUpdate(
  message: ChangeMessage
): message is ChangeMessage & FormattedReviewerUpdateInfo {
  return message.type === 'REVIEWER_UPDATE';
}

export type LabelExtreme = {[labelName: string]: VotingRangeInfo};

export const NEWLINE_PATTERN = /\n/g;

export const PATCH_SET_PREFIX_PATTERN =
  /^(?:Uploaded\s*)?[Pp]atch [Ss]et \d+:\s*(.*)/;

export function sortComments<T extends SortableComment>(comments: T[]): T[] {
  return comments.slice(0).sort((c1, c2) => {
    const d1 = isDraft(c1);
    const d2 = isDraft(c2);
    if (d1 !== d2) return d1 ? 1 : -1;

    const date1 = parseDate(c1.updated);
    const date2 = parseDate(c2.updated);
    const dateDiff = date1.valueOf() - date2.valueOf();
    if (dateDiff !== 0) return dateDiff;

    const id1 = c1.id;
    const id2 = c2.id;
    return id1.localeCompare(id2);
  });
}

export function createUnsavedComment(thread: CommentThread): UnsavedInfo {
  return {
    path: thread.path,
    patch_set: thread.patchNum,
    side: thread.commentSide ?? CommentSide.REVISION,
    line: typeof thread.line === 'number' ? thread.line : undefined,
    range: thread.range,
    parent: thread.mergeParentNum,
    message: '',
    unresolved: true,
    __unsaved: true,
  };
}

export function createPatchsetLevelUnsavedDraft(
  patchNum?: PatchSetNumber,
  message?: string,
  unresolved?: boolean
): UnsavedInfo {
  return {
    patch_set: patchNum,
    message,
    unresolved,
    path: SpecialFilePath.PATCHSET_LEVEL_COMMENTS,
    __unsaved: true,
  };
}

export function createUnsavedReply(
  replyingTo: CommentInfo,
  message: string,
  unresolved: boolean
): UnsavedInfo {
  return {
    path: replyingTo.path,
    patch_set: replyingTo.patch_set,
    side: replyingTo.side,
    line: replyingTo.line,
    range: replyingTo.range,
    parent: replyingTo.parent,
    in_reply_to: replyingTo.id,
    message,
    unresolved,
    __unsaved: true,
  };
}

export function createCommentThreads(comments: CommentInfo[]) {
  const sortedComments = sortComments(comments);
  const threads: CommentThread[] = [];
  const idThreadMap: CommentIdToCommentThreadMap = {};
  for (const comment of sortedComments) {
    // thread and append to it.
    if (comment.in_reply_to) {
      const thread = idThreadMap[comment.in_reply_to];
      if (thread) {
        thread.comments.push(comment);
        if (comment.id) idThreadMap[comment.id] = thread;
        continue;
      }
    }

    // Otherwise, this comment starts its own thread.
    if (!comment.path) {
      throw new Error('Comment missing required "path".');
    }
    const newThread: CommentThread = {
      comments: [comment],
      patchNum: comment.patch_set,
      commentSide: comment.side ?? CommentSide.REVISION,
      mergeParentNum: comment.parent,
      path: comment.path,
      line: comment.line,
      range: comment.range,
      rootId: comment.id,
    };
    if (!comment.line && !comment.range) {
      newThread.line = 'FILE';
    }
    threads.push(newThread);
    if (comment.id) idThreadMap[comment.id] = newThread;
  }
  return threads;
}

export interface CommentThread {
  /**
   * This can only contain at most one draft. And if so, then it is the last
   * comment in this list. This must not contain unsaved drafts.
   */
  comments: Array<CommentInfo | DraftInfo | RobotCommentInfo>;
  /**
   * Identical to the id of the first comment. If this is undefined, then the
   * thread only contains an unsaved draft.
   */
  rootId?: UrlEncodedCommentId;
  /**
   * Note that all location information is typically identical to that of the
   * first comment, but not for ported comments!
   */
  path: string;
  commentSide: CommentSide;
  /* mergeParentNum is the merge parent number only valid for merge commits
     when commentSide is PARENT.
     mergeParentNum is undefined for auto merge commits
     Same as `parent` in CommentInfo.
  */
  mergeParentNum?: number;
  patchNum?: RevisionPatchSetNum;
  /* Different from CommentInfo, which just keeps the line undefined for
     FILE comments. */
  line?: LineNumber;
  range?: CommentRange;
  /**
   * Was the thread ported over from its original location to a newer patchset?
   * If yes, then the location information above contains the ported location,
   * but the comments still have the original location set.
   */
  ported?: boolean;
  /**
   * Only relevant when ported:true. Means that no ported range could be
   * computed. `line` and `range` can be undefined then.
   */
  rangeInfoLost?: boolean;
}

export function equalLocation(t1?: CommentThread, t2?: CommentThread) {
  if (t1 === t2) return true;
  if (t1 === undefined || t2 === undefined) return false;
  return (
    t1.path === t2.path &&
    t1.patchNum === t2.patchNum &&
    t1.commentSide === t2.commentSide &&
    t1.line === t2.line &&
    t1.range?.start_line === t2.range?.start_line &&
    t1.range?.start_character === t2.range?.start_character &&
    t1.range?.end_line === t2.range?.end_line &&
    t1.range?.end_character === t2.range?.end_character
  );
}

export function getLastComment(thread: CommentThread): CommentInfo | undefined {
  const len = thread.comments.length;
  return thread.comments[len - 1];
}

export function getLastPublishedComment(
  thread: CommentThread
): CommentInfo | undefined {
  const publishedComments = thread.comments.filter(c => !isDraftOrUnsaved(c));
  const len = publishedComments.length;
  return publishedComments[len - 1];
}

export function getFirstComment(
  thread: CommentThread
): CommentInfo | undefined {
  return thread.comments[0];
}

export function countComments(thread: CommentThread) {
  return thread.comments.length;
}

export function isPatchsetLevel(thread: CommentThread): boolean {
  return thread.path === SpecialFilePath.PATCHSET_LEVEL_COMMENTS;
}

export function isUnresolved(thread: CommentThread): boolean {
  return !isResolved(thread);
}

export function isResolved(thread: CommentThread): boolean {
  const lastUnresolved = getLastComment(thread)?.unresolved;
  return !lastUnresolved ?? false;
}

export function isDraftThread(thread: CommentThread): boolean {
  return isDraft(getLastComment(thread));
}

export function isMentionedThread(
  thread: CommentThread,
  account?: AccountInfo
) {
  if (!account?.email) return false;
  return getMentionedUsers(thread)
    .map(v => v.email)
    .includes(account.email);
}

export function isRobotThread(thread: CommentThread): boolean {
  return isRobot(getFirstComment(thread));
}

export function hasHumanReply(thread: CommentThread): boolean {
  return countComments(thread) > 1 && !isRobot(getLastComment(thread));
}

export function lastUpdated(thread: CommentThread): Date | undefined {
  // We don't want to re-sort comments when you save a draft reply, so
  // we stick to the timestampe of the last *published* comment.
  const lastUpdated =
    getLastPublishedComment(thread)?.updated ?? getLastComment(thread)?.updated;
  return lastUpdated !== undefined ? parseDate(lastUpdated) : undefined;
}
/**
 * Whether the given comment should be included in the base side of the
 * given patch range.
 */
export function isInBaseOfPatchRange(
  comment: {
    patch_set?: PatchSetNum;
    side?: CommentSide;
    parent?: number;
  },
  range: PatchRange
) {
  // If the base of the patch range is a parent of a merge, and the comment
  // appears on a specific parent then only show the comment if the parent
  // index of the comment matches that of the range.
  if (comment.parent && comment.side === CommentSide.PARENT) {
    return (
      isMergeParent(range.basePatchNum) &&
      comment.parent === getParentIndex(range.basePatchNum)
    );
  }

  // If the base of the range is the parent of the patch:
  if (
    range.basePatchNum === PARENT &&
    comment.side === CommentSide.PARENT &&
    comment.patch_set === range.patchNum
  ) {
    return true;
  }
  // If the base of the range is not the parent of the patch:
  return (
    range.basePatchNum !== PARENT &&
    comment.side !== CommentSide.PARENT &&
    comment.patch_set === range.basePatchNum
  );
}

/**
 * Whether the given comment should be included in the revision side of the
 * given patch range.
 */
export function isInRevisionOfPatchRange(
  comment: {
    patch_set?: PatchSetNum;
    side?: CommentSide;
  },
  range: PatchRange
) {
  return (
    comment.side !== CommentSide.PARENT && comment.patch_set === range.patchNum
  );
}

/**
 * Whether the given comment should be included in the given patch range.
 */
export function isInPatchRange(
  comment: CommentBasics,
  range: PatchRange
): boolean {
  return (
    isInBaseOfPatchRange(comment, range) ||
    isInRevisionOfPatchRange(comment, range)
  );
}

export function getPatchRangeForCommentUrl(
  comment: Comment,
  latestPatchNum: RevisionPatchSetNum
) {
  if (!comment.patch_set) throw new Error('Missing comment.patch_set');

  // TODO(dhruvsri): Add handling for comment left on parents of merge commits
  if (comment.side === CommentSide.PARENT) {
    return {
      patchNum: comment.patch_set,
      basePatchNum: PARENT,
    };
  } else if (latestPatchNum === comment.patch_set) {
    return {
      patchNum: latestPatchNum,
      basePatchNum: PARENT,
    };
  } else {
    return {
      patchNum: latestPatchNum,
      basePatchNum: comment.patch_set as BasePatchSetNum,
    };
  }
}

export function computeDiffFromContext(
  context: ContextLine[],
  path: string,
  content_type?: string
) {
  // do not render more than 20 lines of context
  context = context.slice(0, 20);
  const diff: DiffInfo = {
    meta_a: {
      name: '',
      content_type: '',
      lines: 0,
      web_links: [],
    },
    meta_b: {
      name: path,
      content_type: content_type || '',
      lines: context.length + context?.[0].line_number,
      web_links: [],
    },
    change_type: 'MODIFIED',
    intraline_status: 'OK',
    diff_header: [],
    content: [
      {
        skip: context[0].line_number - 1,
      },
      {
        b: context.map(line => line.context_line),
      },
    ],
  };
  return diff;
}

export function getCommentAuthors(
  threads?: CommentThread[],
  user?: AccountDetailInfo
) {
  if (!threads || !user) return [];
  const ids = new Set();
  const authors: AccountInfo[] = [];
  threads.forEach(t =>
    t.comments.forEach(c => {
      if (isDraft(c) && !ids.has(user._account_id)) {
        ids.add(user._account_id);
        authors.push(user);
        return;
      }
      if (c.author && !ids.has(c.author._account_id)) {
        ids.add(c.author._account_id);
        authors.push(c.author);
      }
    })
  );
  return authors;
}

/**
 * Add path info to every comment as CommentInfo returned from server does not
 * have that.
 */
export function addPath<T>(comments: {[path: string]: T[]} = {}): {
  [path: string]: Array<T & {path: string}>;
} {
  const updatedComments: {[path: string]: Array<T & {path: string}>} = {};
  for (const filePath of Object.keys(comments)) {
    updatedComments[filePath] = (comments[filePath] || []).map(comment => {
      return {...comment, path: filePath};
    });
  }
  return updatedComments;
}

/**
 * Add __draft:true to all drafts returned from server so that they can be told
 * apart from published comments easily.
 */
export function addDraftProp(
  draftsByPath: {[path: string]: CommentInfo[]} = {}
) {
  const updated: {[path: string]: DraftInfo[]} = {};
  for (const filePath of Object.keys(draftsByPath)) {
    updated[filePath] = (draftsByPath[filePath] ?? []).map(draft => {
      return {...draft, __draft: true};
    });
  }
  return updated;
}

export function reportingDetails(comment: CommentBasics) {
  return {
    id: comment?.id,
    message_length: comment?.message?.trim().length,
    in_reply_to: comment?.in_reply_to,
    unresolved: comment?.unresolved,
    path_length: comment?.path?.length,
    line: comment?.range?.start_line ?? comment?.line,
    unsaved: isUnsaved(comment),
  };
}

export const USER_SUGGESTION_INFO_STRING = 'suggestion';
export const USER_SUGGESTION_START_PATTERN = `\`\`\`${USER_SUGGESTION_INFO_STRING}\n`;

// This can either mean a user or a checks provided fix.
// "Provided" means that the fix is sent along with the request
// when previewing and applying the fix. This is in contrast to
// robot comment fixes, which are stored in the backend, and they
// are referenced by a unique `FixId`;
export const PROVIDED_FIX_ID = 'provided_fix' as FixId;

export function hasUserSuggestion(comment: Comment) {
  return comment.message?.includes(USER_SUGGESTION_START_PATTERN) ?? false;
}

export function getUserSuggestion(comment: Comment) {
  if (!comment.message) return;
  const start =
    comment.message.indexOf(USER_SUGGESTION_START_PATTERN) +
    USER_SUGGESTION_START_PATTERN.length;
  const end = comment.message.indexOf('\n```', start);
  return comment.message.substring(start, end);
}

export function getContentInCommentRange(
  fileContent: string,
  comment: Comment
) {
  const lines = fileContent.split('\n');
  if (comment.range) {
    const range = comment.range;
    return lines.slice(range.start_line - 1, range.end_line).join('\n');
  }
  return lines[comment.line! - 1];
}

export function createUserFixSuggestion(
  comment: Comment,
  line: string,
  replacement: string
): FixSuggestionInfo[] {
  const lastLine = line.split('\n').pop();
  return [
    {
      fix_id: PROVIDED_FIX_ID,
      description: 'User suggestion',
      replacements: [
        {
          path: comment.path!,
          range: {
            start_line: comment.range?.start_line ?? comment.line!,
            start_character: 0,
            end_line: comment.range?.end_line ?? comment.line!,
            end_character: lastLine!.length,
          },
          replacement,
        },
      ],
    },
  ];
}

function getMentionedUsers(thread: CommentThread) {
  return thread.comments.map(c => extractMentionedUsers(c.message)).flat();
}

export function getMentionedThreads(
  threads: CommentThread[],
  account: AccountInfo
) {
  if (!account.email) return [];
  return threads.filter(t =>
    getMentionedUsers(t)
      .map(v => v.email)
      .includes(account.email)
  );
}

export function findComment(
  comments: {
    [path: string]: (CommentInfo | DraftInfo)[];
  },
  commentId: UrlEncodedCommentId
) {
  if (!commentId) return undefined;
  let comment;
  for (const path of Object.keys(comments)) {
    comment = comment || comments[path].find(c => c.id === commentId);
  }
  return comment;
}
