/**
 * @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} from '../../api/rest-api';
import {FixSuggestionInfo, FixReplacementInfo} from '../../types/common';
import {OpenFixPreviewEventDetail} from '../../types/events';
import {isDefined} from '../../types/types';
import {PROVIDED_FIX_ID} from '../../utils/comment-util';
import {assert, 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'};
    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';
  }
}

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,
  };
  return {
    name: 'Show Fix',
    callback: () => {
      fire(target, 'open-fix-preview', eventDetail);
      return undefined;
    },
  };
}

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

  return {
    description: fix.description ?? `Fix provided by ${checkName}`,
    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: CheckRun) {
  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): 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 = worstCategory(run);
    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: CheckRun, category: Category) {
  return getResultsOf(run, category).length > 0;
}

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

export function compareByWorstCategory(a: CheckRun, b: CheckRun) {
  const catComp = catLevel(worstCategory(b)) - catLevel(worstCategory(a));
  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 (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: [],
    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);
}
