/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  Action,
  Category,
  CheckResult as CheckResultApi,
  CheckRun as CheckRunApi,
  Fix,
  Link,
  LinkIcon,
  Replacement,
  RunStatus,
} from '../../api/checks';
import {
  PatchSetNumber,
  RevisionPatchSetNum,
  FixReplacementInfo,
} from '../../api/rest-api';
import {CommentSide} from '../../constants/constants';
import {FixSuggestionInfo, DraftInfo} from '../../types/common';
import {OpenFixPreviewEventDetail} from '../../types/events';
import {isDefined} from '../../types/types';
import {PROVIDED_FIX_ID, createNew} from '../../utils/comment-util';
import {assert, assertIsDefined, assertNever} from '../../utils/common-util';
import {fire} from '../../utils/event-util';
import {CheckResult, CheckRun, RunResult} from './checks-model';

export interface ChecksIcon {
  name: string;
  filled?: boolean;
}

export function iconForLink(linkIcon?: LinkIcon): ChecksIcon {
  if (linkIcon === undefined) return {name: 'open_in_new'};
  switch (linkIcon) {
    case LinkIcon.EXTERNAL:
      return {name: 'open_in_new'};
    case LinkIcon.IMAGE:
      return {name: 'image', filled: true};
    case LinkIcon.HISTORY:
      return {name: 'history'};
    case LinkIcon.DOWNLOAD:
      return {name: 'download'};
    case LinkIcon.DOWNLOAD_MOBILE:
      return {name: 'system_update'};
    case LinkIcon.HELP_PAGE:
      return {name: 'help'};
    case LinkIcon.REPORT_BUG:
      return {name: 'bug_report', filled: true};
    case LinkIcon.CODE:
      return {name: 'code'};
    case LinkIcon.FILE_PRESENT:
      return {name: 'file_present'};
    case LinkIcon.VIEW_TIMELINE:
      return {name: 'view_timeline'};
    default:
      // We don't throw an assertion error here, because plugins don't have to
      // be written in TypeScript, so we may encounter arbitrary strings for
      // linkIcon.
      return {name: 'open_in_new'};
  }
}

export function tooltipForLink(linkIcon?: LinkIcon) {
  if (linkIcon === undefined) return 'Link to details';
  switch (linkIcon) {
    case LinkIcon.EXTERNAL:
      return 'Link to details';
    case LinkIcon.IMAGE:
      return 'Link to image';
    case LinkIcon.HISTORY:
      return 'Link to result history';
    case LinkIcon.DOWNLOAD:
      return 'Download';
    case LinkIcon.DOWNLOAD_MOBILE:
      return 'Download';
    case LinkIcon.HELP_PAGE:
      return 'Link to help page';
    case LinkIcon.REPORT_BUG:
      return 'Link for reporting a problem';
    case LinkIcon.CODE:
      return 'Link to code';
    case LinkIcon.FILE_PRESENT:
      return 'Link to file';
    default:
      // We don't throw an assertion error here, because plugins don't have to
      // be written in TypeScript, so we may encounter arbitrary strings for
      // linkIcon.
      return 'Link to details';
  }
}

function pleaseFixMessage(result: RunResult) {
  return `Please fix this ${result.category} reported by ${result.checkName}: ${result.summary}

${result.message}`;
}

export function createPleaseFixComment(result: RunResult): DraftInfo {
  const pointer = result.codePointers?.[0];
  assertIsDefined(pointer, 'codePointer');
  return {
    ...createNew(pleaseFixMessage(result), true),
    path: pointer.path,
    patch_set: result.patchset as RevisionPatchSetNum,
    side: CommentSide.REVISION,
    line: pointer.range.end_line ?? pointer.range.start_line,
    range: pointer.range,
  };
}

export function createFixAction(
  target: EventTarget,
  result?: RunResult
): Action | undefined {
  if (!result?.patchset) return;
  if (!result?.fixes) return;
  const fixSuggestions = result.fixes
    .map(f => rectifyFix(f, result?.checkName))
    .filter(isDefined);
  if (fixSuggestions.length === 0) return;
  const eventDetail: OpenFixPreviewEventDetail = {
    patchNum: result.patchset as PatchSetNumber,
    fixSuggestions,
    onCloseFixPreviewCallbacks: [],
  };
  return {
    name: 'Show Fix',
    callback: () => {
      fire(target, 'open-fix-preview', eventDetail);
      return undefined;
    },
  };
}

export function rectifyFix(
  fix: Fix | undefined,
  checkName: string | undefined
): FixSuggestionInfo | undefined {
  if (!fix?.replacements || !checkName) return undefined;
  const replacements = fix.replacements
    .map(rectifyReplacement)
    .filter(isDefined);
  if (replacements.length === 0) return undefined;

  return {
    description: [fix.description, `Fix provided by ${checkName}`]
      .filter(Boolean)
      .join(' - '),
    fix_id: PROVIDED_FIX_ID,
    replacements,
  };
}

export function rectifyReplacement(
  r: Replacement | undefined
): FixReplacementInfo | undefined {
  if (!r?.path) return undefined;
  if (!r?.range) return undefined;
  if (r?.replacement === undefined) return undefined;
  if (!Number.isInteger(r.range.start_line)) return undefined;
  if (!Number.isInteger(r.range.end_line)) return undefined;
  if (!Number.isInteger(r.range.start_character)) return undefined;
  if (!Number.isInteger(r.range.end_character)) return undefined;
  return r;
}

export function worstCategory(run: CheckRunApi) {
  if (hasResultsOf(run, Category.ERROR)) return Category.ERROR;
  if (hasResultsOf(run, Category.WARNING)) return Category.WARNING;
  if (hasResultsOf(run, Category.INFO)) return Category.INFO;
  if (hasResultsOf(run, Category.SUCCESS)) return Category.SUCCESS;
  return undefined;
}

export function isCategory(
  catStat?: Category | RunStatus
): catStat is Category {
  return (
    catStat === Category.ERROR ||
    catStat === Category.WARNING ||
    catStat === Category.INFO ||
    catStat === Category.SUCCESS
  );
}

export function isStatus(catStat?: Category | RunStatus): catStat is RunStatus {
  return (
    catStat === RunStatus.COMPLETED ||
    catStat === RunStatus.RUNNABLE ||
    catStat === RunStatus.SCHEDULED ||
    catStat === RunStatus.RUNNING
  );
}

export function labelFor(catStat: Category | RunStatus) {
  switch (catStat) {
    case Category.ERROR:
      return 'error';
    case Category.INFO:
      return 'info';
    case Category.WARNING:
      return 'warning';
    case Category.SUCCESS:
      return 'success';
    case RunStatus.COMPLETED:
      return 'completed';
    case RunStatus.RUNNABLE:
      return 'runnable';
    case RunStatus.RUNNING:
      return 'running';
    case RunStatus.SCHEDULED:
      return 'scheduled';
    default:
      assertNever(catStat, `Unsupported category/status: ${catStat}`);
  }
}

export function iconFor(catStat: Category | RunStatus): ChecksIcon {
  switch (catStat) {
    case Category.ERROR:
      return {name: 'error', filled: true};
    case Category.INFO:
      return {name: 'info'};
    case Category.WARNING:
      return {name: 'warning', filled: true};
    case Category.SUCCESS:
      return {name: 'check_circle'};
    // Note that this is only for COMPLETED without results!
    case RunStatus.COMPLETED:
      return {name: 'check_circle'};
    case RunStatus.RUNNABLE:
      return {name: ''};
    case RunStatus.RUNNING:
      return {name: 'timelapse'};
    case RunStatus.SCHEDULED:
      return {name: 'pending_actions'};
    default:
      assertNever(catStat, `Unsupported category/status: ${catStat}`);
  }
}

export enum PRIMARY_STATUS_ACTIONS {
  RERUN = 'rerun',
  RUN = 'run',
}

export function toCanonicalAction(action: Action, status: RunStatus) {
  let name = action.name.toLowerCase();
  if (status === RunStatus.COMPLETED && (name === 'run' || name === 're-run')) {
    name = PRIMARY_STATUS_ACTIONS.RERUN;
  }
  return {...action, name};
}

export function headerForStatus(status: RunStatus) {
  switch (status) {
    case RunStatus.COMPLETED:
      return 'Completed';
    case RunStatus.RUNNABLE:
      return 'Not run';
    case RunStatus.RUNNING:
      return 'Running';
    case RunStatus.SCHEDULED:
      return 'Scheduled';
    default:
      assertNever(status, `Unsupported status: ${status}`);
  }
}

function primaryActionName(status: RunStatus) {
  switch (status) {
    case RunStatus.COMPLETED:
      return PRIMARY_STATUS_ACTIONS.RERUN;
    case RunStatus.RUNNABLE:
      return PRIMARY_STATUS_ACTIONS.RUN;
    case RunStatus.RUNNING:
    case RunStatus.SCHEDULED:
      return undefined;
    default:
      assertNever(status, `Unsupported status: ${status}`);
  }
}

export function primaryRunAction(run?: CheckRun): Action | undefined {
  if (!run) return undefined;
  return runActions(run).filter(
    action => !action.disabled && action.name === primaryActionName(run.status)
  )[0];
}

export function runActions(run?: CheckRun | RunResult): Action[] {
  if (!run?.actions) return [];
  return run.actions.map(action => toCanonicalAction(action, run.status));
}

export function iconForRun(run: CheckRun) {
  if (run.status !== RunStatus.COMPLETED) {
    return iconFor(run.status);
  } else {
    const category = run.worstCategory;
    return category ? iconFor(category) : iconFor(run.status);
  }
}

export function hasCompleted(run: CheckRun) {
  return run.status === RunStatus.COMPLETED;
}

export function isRunningOrScheduled(run: CheckRun) {
  return run.status === RunStatus.RUNNING || run.status === RunStatus.SCHEDULED;
}

export function isRunningScheduledOrCompleted(run: CheckRun) {
  return (
    run.status === RunStatus.COMPLETED ||
    run.status === RunStatus.RUNNING ||
    run.status === RunStatus.SCHEDULED
  );
}

export function hasCompletedWithoutResults(run: CheckRun) {
  return run.status === RunStatus.COMPLETED && (run.results ?? []).length === 0;
}

export function hasCompletedWith(run: CheckRun, category: Category) {
  return hasCompleted(run) && hasResultsOf(run, category);
}

export function hasResults(run: CheckRun): boolean {
  return (run.results ?? []).length > 0;
}

export function allResults(runs: CheckRun[]): CheckResult[] {
  return runs.reduce(
    (results: CheckResult[], run: CheckRun) => [
      ...results,
      ...(run.results ?? []),
    ],
    []
  );
}

export function hasResultsOf(run: CheckRunApi, category: Category) {
  return getResultsOf(run, category).length > 0;
}

export function getResultsOf(run: CheckRunApi, category: Category) {
  return (run.results ?? []).filter(r => r.category === category);
}

export function compareByWorstCategory(a: CheckRun, b: CheckRun) {
  const catComp = catLevel(b.worstCategory) - catLevel(a.worstCategory);
  if (catComp !== 0) return catComp;
  const statusComp = runLevel(b.status) - runLevel(a.status);
  return statusComp;
}

function catLevel(cat?: Category) {
  if (!cat) return -1;
  switch (cat) {
    case Category.SUCCESS:
      return 0;
    case Category.INFO:
      return 1;
    case Category.WARNING:
      return 2;
    case Category.ERROR:
      return 3;
  }
}

function runLevel(status: RunStatus) {
  switch (status) {
    case RunStatus.COMPLETED:
      return 0;
    case RunStatus.RUNNABLE:
      return 1;
    case RunStatus.RUNNING:
      return 2;
    case RunStatus.SCHEDULED:
      return 3;
    default:
      assertNever(status, `Unsupported status: ${status}`);
  }
}

export interface AttemptDetail {
  attempt?: AttemptChoice;
  icon?: ChecksIcon;
}

export interface AttemptInfo {
  latestAttempt: AttemptChoice;
  isSingleAttempt: boolean;
  attempts: AttemptDetail[];
}

export type AttemptChoice = number | 'latest' | 'all';
export const ALL_ATTEMPTS = 'all' as AttemptChoice;
export const LATEST_ATTEMPT = 'latest' as AttemptChoice;

export function isAttemptChoice(x: number | string): x is AttemptChoice {
  if (typeof x === 'string') {
    return x === ALL_ATTEMPTS || x === LATEST_ATTEMPT;
  }
  if (typeof x === 'number') {
    return x >= 0;
  }
  return false;
}

export function stringToAttemptChoice(
  s?: string | null
): AttemptChoice | undefined {
  if (s === undefined) return undefined;
  if (s === null) return undefined;
  if (s === '') return undefined;
  if (isAttemptChoice(s)) return s;
  const n = Number(s);
  if (isAttemptChoice(n)) return n;
  return undefined;
}

export function attemptChoiceLabel(attempt: AttemptChoice): string {
  if (attempt === LATEST_ATTEMPT) return 'Latest Attempt';
  if (attempt === ALL_ATTEMPTS) return 'All Attempts';
  return `Attempt ${attempt}`;
}

export function sortAttemptDetails(a: AttemptDetail, b: AttemptDetail): number {
  return sortAttemptChoices(a.attempt, b.attempt);
}

export function sortAttemptChoices(
  a?: AttemptChoice,
  b?: AttemptChoice
): number {
  if (a === b) return 0;
  if (a === undefined) return -1;
  if (b === undefined) return 1;
  if (a === LATEST_ATTEMPT) return -1;
  if (b === LATEST_ATTEMPT) return 1;
  if (a === ALL_ATTEMPTS) return -1;
  if (b === ALL_ATTEMPTS) return 1;
  assert(typeof a === 'number', `unexpected attempt ${a}`);
  assert(typeof b === 'number', `unexpected attempt ${b}`);
  return a - b;
}

export function createAttemptMap(runs: CheckRunApi[]) {
  const map = new Map<string, AttemptInfo>();
  for (const run of runs) {
    const value = map.get(run.checkName);
    const detail: AttemptDetail = {
      attempt: run.attempt ?? 0,
      icon: iconForRun(fromApiToInternalRun(run)),
    };
    if (value === undefined) {
      map.set(run.checkName, {
        latestAttempt: run.attempt ?? 0,
        isSingleAttempt: true,
        attempts: [detail],
      });
      continue;
    }
    if (!run.attempt || !value.latestAttempt) {
      throw new Error(
        'If multiple run attempts are provided, ' +
          'then each run must have the "attempt" property set.'
      );
    }
    value.isSingleAttempt = false;
    if (
      value.latestAttempt !== 'all' &&
      value.latestAttempt !== 'latest' &&
      run.attempt > value.latestAttempt
    ) {
      value.latestAttempt = run.attempt;
    }
    value.attempts.push(detail);
  }
  return map;
}

export function fromApiToInternalRun(run: CheckRunApi): CheckRun {
  return {
    ...run,
    pluginName: 'fake',
    internalRunId: 'fake',
    isSingleAttempt: false,
    isLatestAttempt: false,
    attemptDetails: [],
    worstCategory: worstCategory(run),
    results: (run.results ?? []).map(fromApiToInternalResult),
  };
}

export function fromApiToInternalResult(result: CheckResultApi): CheckResult {
  return {
    ...result,
    internalResultId: 'fake',
  };
}

function allPrimaryLinks(result?: CheckResultApi): Link[] {
  return (result?.links ?? []).filter(link => link.primary);
}

export function firstPrimaryLink(result?: CheckResultApi): Link | undefined {
  return allPrimaryLinks(result).find(link => link.icon === LinkIcon.EXTERNAL);
}

export function otherPrimaryLinks(result?: CheckResultApi): Link[] {
  const first = firstPrimaryLink(result);
  return allPrimaryLinks(result).filter(link => link !== first);
}

export function secondaryLinks(result?: CheckResultApi): Link[] {
  return (result?.links ?? []).filter(link => !link.primary);
}

export function computeIsExpandable(result?: CheckResultApi) {
  const hasMessage = !!result?.message;
  const hasMultipleLinks = (result?.links ?? []).length > 1;
  const hasPointers = (result?.codePointers ?? []).length > 0;
  const hasFixes = (result?.fixes ?? []).length > 0;
  return hasMessage || hasMultipleLinks || hasPointers || hasFixes;
}
