import {
  RevisionInfo,
  ChangeInfo,
  PatchSetNum,
  EDIT,
  PARENT,
  PatchSetNumber,
  BasePatchSetNum,
  RevisionPatchSetNum,
  BranchName,
  CommitId,
} from '../types/common';
import {EditRevisionInfo, ParsedChangeInfo} from '../types/types';
import {assert} from './common-util';

/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

// Tags identifying ChangeMessages that move change into WIP state.
const WIP_TAGS = [
  'autogenerated:gerrit:newWipPatchSet',
  'autogenerated:gerrit:setWorkInProgress',
];

// Tags identifying ChangeMessages that move change out of WIP state.
const READY_TAGS = ['autogenerated:gerrit:setReadyForReview'];

export const CURRENT = 'current';

export interface PatchSet {
  num: RevisionPatchSetNum;
  desc: string | undefined;
  sha: CommitId;
  wip?: boolean;
}

/**
 * Whether the given patch is a numbered parent of a merge (i.e. a negative
 * number).
 */
export function isMergeParent(n: PatchSetNum) {
  return `${n}`[0] === '-';
}

/**
 * Whether the given patch is a parent, either a regular parent or a merge
 * parent.
 */
export function isAParent(n: PatchSetNum) {
  return n === PARENT || isMergeParent(n);
}

export function isPatchSetNum(patchset: string) {
  if (!isNaN(Number(patchset))) return true;
  return patchset === EDIT || patchset === PARENT;
}

export function convertToPatchSetNum(
  patchset: string | undefined
): PatchSetNum | undefined {
  if (!patchset) return undefined;
  if (!isPatchSetNum(patchset)) {
    console.error('string is not of type PatchSetNum');
  }
  const value = Number(patchset);
  if (!isNaN(value)) return value as PatchSetNum;
  return patchset as PatchSetNum;
}

export function isNumber(psn?: PatchSetNum): psn is PatchSetNumber {
  return typeof psn === 'number';
}

/**
 * Given an object of revisions, get a particular revision based on patch
 * num.
 *
 * @return The correspondent revision obj from {revisions}
 */
export function getRevisionByPatchNum(
  revisions: (RevisionInfo | EditRevisionInfo)[],
  patchNum: PatchSetNum
) {
  for (const rev of revisions) {
    if (rev._number === patchNum) {
      return rev;
    }
  }
  if (revisions.length > 0) console.warn('no revision found');
  return;
}

export function getShaByPatchNum(
  revisions: {[revisionId: string]: RevisionInfo | EditRevisionInfo},
  patchNum: RevisionPatchSetNum
) {
  for (const [sha, rev] of Object.entries(revisions)) {
    if (rev._number === patchNum) return sha;
  }
  return undefined;
}

/**
 * Find change edit revision if change edit exists.
 */
export function findEdit(
  revisions: Array<RevisionInfo | EditRevisionInfo>
): EditRevisionInfo | undefined {
  const editRev = revisions.find(info => info._number === EDIT);
  return editRev as EditRevisionInfo | undefined;
}

/**
 * Find change edit base revision if change edit exists.
 *
 * @return change edit parent revision or null if change edit
 *     doesn't exist.
 */
export function findEditParentRevision(
  revisions: Array<RevisionInfo | EditRevisionInfo>
) {
  const editInfo = findEdit(revisions);
  if (!editInfo) return null;

  return revisions.find(info => info._number === editInfo.basePatchNum) || null;
}

/**
 * Find change edit base patch set number if change edit exists.
 *
 * @return Change edit patch set number or -1.
 *
 */
export function findEditParentPatchNum(
  revisions: Array<RevisionInfo | EditRevisionInfo>
) {
  const revisionInfo = findEditParentRevision(revisions);
  // finding parent of EDIT patchset, hence revisionInfo._number cannot be
  // EDIT and must be a number
  // TODO(TS): find a way to avoid 'as'
  return revisionInfo ? (revisionInfo._number as number) : -1;
}

/**
 * Sort given revisions array according to the patch set number, in
 * descending order.
 * The sort algorithm is change edit aware. Change edit has patch set number
 * equals EDIT, but must appear after the patch set it was based on.
 * Example: change edit is based on patch set 2, and another patch set was
 * uploaded after change edit creation, the sorted order should be:
 * 3, edit, 2, 1.
 *
 */
export function sortRevisions<T extends RevisionInfo | EditRevisionInfo>(
  revisions: T[]
): T[] {
  const editParent: number = findEditParentPatchNum(revisions);
  // Map a normal patchNum to 2 * (patchNum - 1) + 1... I.e. 1 -> 1,
  // 2 -> 3, 3 -> 5, etc.
  // Map an edit to the patchNum of parent*2... I.e. edit on 2 -> 4.
  // TODO(TS): find a way to avoid 'as'
  const num = (r: T) =>
    r._number === EDIT ? 2 * editParent : 2 * ((r._number as number) - 1) + 1;
  return revisions.sort((a, b) => num(b) - num(a));
}

/**
 * Construct a chronological list of patch sets derived from change details.
 * Each element of this list is an object with the following properties:
 *
 *   * num The number identifying the patch set
 *   * desc Optional patch set description
 *   * wip If true, this patch set was never subject to review.
 *   * sha hash of the commit
 *
 * The wip property is determined by the change's current work_in_progress
 * property and its log of change messages.
 *
 * @return Sorted list of patch set objects, as described
 *     above
 */
export function computeAllPatchSets(
  change: ChangeInfo | ParsedChangeInfo | undefined
): PatchSet[] {
  if (!change) return [];

  let patchNums: PatchSet[] = [];
  if (change.revisions && Object.keys(change.revisions).length) {
    const changeRevisions = change.revisions;
    const revisions = Object.keys(change.revisions).map(sha => {
      return {sha, ...changeRevisions[sha]};
    });
    patchNums = sortRevisions(revisions).map(e => {
      // TODO(kaspern): Mark which patchset an edit was made on, if an
      // edit exists -- perhaps with a temporary description.
      return {
        num: e._number,
        desc: e.description,
        sha: e.sha as CommitId,
      };
    });
  }
  return computeWipForPatchSets(change, patchNums);
}

/**
 * Populate the wip properties of the given list of patch sets.
 *
 * @param change The change details
 * @param patchNums Sorted list of patch set objects, as
 *     generated by computeAllPatchSets
 * @return The given list of patch set objects, with the
 *     wip property set on each of them
 */
function computeWipForPatchSets(
  change: ChangeInfo | ParsedChangeInfo,
  patchNums: PatchSet[]
) {
  if (!change.messages || !change.messages.length) {
    return patchNums;
  }
  // TODO(TS): replace with Map<PatchNum, boolean>
  const psWip: Map<string, boolean> = new Map<string, boolean>();
  let wip = !!change.work_in_progress;
  for (let i = 0; i < change.messages.length; i++) {
    const msg = change.messages[i];
    if (msg.tag && WIP_TAGS.includes(msg.tag)) {
      wip = true;
    } else if (msg.tag && READY_TAGS.includes(msg.tag)) {
      wip = false;
    }
    if (
      msg._revision_number &&
      psWip.get(`${msg._revision_number}`) !== false
    ) {
      psWip.set(`${msg._revision_number}`, wip);
    }
  }

  for (let i = 0; i < patchNums.length; i++) {
    patchNums[i].wip = psWip.get(`${patchNums[i].num}`);
  }
  return patchNums;
}

export const _testOnly_computeWipForPatchSets = computeWipForPatchSets;

export function computeLatestPatchNum(
  allPatchSets?: PatchSet[]
): PatchSetNumber | undefined {
  if (!allPatchSets || !allPatchSets.length) {
    return undefined;
  }
  let latest = allPatchSets[0].num;
  if (latest === EDIT) {
    latest = allPatchSets[1].num;
  }
  assert(isNumber(latest), 'Latest patchset cannot be EDIT or PARENT.');
  return latest;
}

// Basically is computeLatestPatchNum but allows "edits".
export function computeLatestPatchNumWithEdit(
  allPatchSets?: PatchSet[]
): RevisionPatchSetNum | undefined {
  if (!allPatchSets || !allPatchSets.length) {
    return undefined;
  }
  return allPatchSets[0].num;
}

export function computePredecessor(
  patchset?: PatchSetNum
): BasePatchSetNum | undefined {
  if (!patchset || patchset === PARENT || patchset === EDIT) {
    return undefined;
  }
  if (patchset === 1) return PARENT;
  return (Number(patchset) - 1) as BasePatchSetNum;
}

export function hasEditBasedOnCurrentPatchSet(
  allPatchSets: PatchSet[]
): boolean {
  if (!allPatchSets || allPatchSets.length < 2) {
    return false;
  }
  return allPatchSets[0].num === EDIT;
}

/**
 * @param revisions A sorted array of revisions.
 *
 * @return the index of the revision with the given patchNum.
 */
export function findSortedIndex(
  patchNum: PatchSetNum,
  revisions: (RevisionInfo | EditRevisionInfo)[]
) {
  revisions = revisions || [];
  const findNum = (rev: RevisionInfo | EditRevisionInfo) =>
    `${rev._number}` === `${patchNum}`;
  return revisions.findIndex(findNum);
}

/**
 * Convert parent indexes from patch range expressions to numbers.
 * For example, in a patch range expression `"-3"` becomes `3`.
 */
export function getParentIndex(rangeBase: PatchSetNum) {
  return -Number(`${rangeBase}`);
}

export function shorten(sha?: string) {
  // Using the first 7 characters of the 40 chars commit sha is standard Git convention.
  return sha?.substring(0, 7);
}

export function branchName(branch?: string | BranchName): BranchName {
  if (!branch) return '' as BranchName;
  if (branch.startsWith('refs/heads/')) {
    return branch.substring('refs/heads/'.length) as BranchName;
  }
  return branch as BranchName;
}

export function getParentCommit(
  rev?: RevisionInfo | EditRevisionInfo,
  index?: number
) {
  const parents = rev?.parents_data ?? [];
  const parent = parents[index ?? 0];
  if (!parent) return '';
  return shorten(parent.commit_id) ?? '';
}

export function getParentInfoString(
  rev?: RevisionInfo | EditRevisionInfo,
  index?: number
) {
  const parents = rev?.parents_data ?? [];
  const parent = parents[index ?? 0];
  if (!parent || parent.is_merged_in_target_branch) return '';

  if (index === 0) {
    if (parent.change_number) {
      return `Patchset ${parent.patch_set_number} of Change ${parent.change_number}`;
    } else {
      return 'Warning: The base commit is not known (aka reachable) in the target branch.';
    }
  } else {
    // For merge changes the parents with index > 0 are expected to be from a different branch.
    return 'Other branch';
  }
}
