import {
  RevisionInfo,
  ChangeInfo,
  PatchSetNum,
  EditPatchSetNum,
} from '../types/common';
import {RestApiService} from '../services/services/gr-rest-api/gr-rest-api';
import {ParsedChangeInfo} from '../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';

/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// 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'];

// TODO(TS): Replace usages of these constants by
// EditPatchSetNum and ParentPatchSetNum in common.ts.
export const SPECIAL_PATCH_SET_NUM = {
  EDIT: 'edit',
  PARENT: 'PARENT',
};

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

interface RevisionWithSha extends RevisionInfo {
  sha: string;
}

interface PatchRange {
  patchNum?: PatchSetNum;
  basePatchNum?: PatchSetNum;
}

interface PatchRangeRecord {
  base: PatchRange;
}

/**
 * As patchNum can be either a string (e.g. 'edit', 'PARENT') OR a number,
 * this function checks for patchNum equality.
 *
 */
export function patchNumEquals(a?: PatchSetNum, b?: PatchSetNum) {
  if (a === undefined) {
    return a === b;
  }
  // TODO(TS): replace with a===b when the whole code is converted to ts
  return `${a}` === `${b}`;
}

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

/**
 * 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[],
  patchNum: PatchSetNum
) {
  for (const rev of revisions) {
    if (patchNumEquals(rev._number, patchNum)) {
      return rev;
    }
  }
  console.warn('no revision found');
  return;
}

/**
 * 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: RevisionInfo[]) {
  const editInfo = revisions.find(info => info._number === EditPatchSetNum);

  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: RevisionInfo[]) {
  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>(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 === EditPatchSetNum
      ? 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: ParsedChangeInfo): PatchSet[] {
  if (!change) {
    return [];
  }

  let patchNums: PatchSet[] = [];
  if (change.revisions && Object.keys(change.revisions).length) {
    const changeRevisions = change.revisions;
    const revisions: RevisionWithSha[] = Object.keys(change.revisions).map(
      sha => {
        return {sha, ...changeRevisions[sha]};
      }
    );
    patchNums = sortRevisions(revisions).map((e: RevisionWithSha) => {
      // 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,
      };
    });
  }
  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: 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();
  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[]) {
  if (!allPatchSets || !allPatchSets.length) {
    return undefined;
  }
  if (allPatchSets[0].num === EditPatchSetNum) {
    return allPatchSets[1].num;
  }
  return allPatchSets[0].num;
}

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

export function hasEditPatchsetLoaded(patchRangeRecord: PatchRangeRecord) {
  const patchRange = patchRangeRecord.base;
  if (!patchRange) {
    return false;
  }
  return (
    patchRange.patchNum === EditPatchSetNum ||
    patchRange.basePatchNum === EditPatchSetNum
  );
}

/**
 * Check whether there is no newer patch than the latest patch that was
 * available when this change was loaded.
 *
 * @return A promise that yields true if the latest patch
 *     has been loaded, and false if a newer patch has been uploaded in the
 *     meantime. The promise is rejected on network error.
 */
export function fetchChangeUpdates(
  change: ChangeInfo,
  restAPI: RestApiService
) {
  const knownLatest = computeLatestPatchNum(computeAllPatchSets(change));
  return restAPI.getChangeDetail(change._number).then(detail => {
    if (!detail) {
      const error = new Error('Change detail not found.');
      return Promise.reject(error);
    }
    const actualLatest = computeLatestPatchNum(computeAllPatchSets(detail));
    if (!actualLatest || !knownLatest) {
      const error = new Error('Unable to check for latest patchset.');
      return Promise.reject(error);
    }
    return {
      isLatest: actualLatest <= knownLatest,
      newStatus: change.status !== detail.status ? detail.status : null,
      newMessages:
        (change.messages || []).length < (detail.messages || []).length,
    };
  });
}

/**
 * @param revisions A sorted array of revisions.
 *
 * @return the index of the revision with the given patchNum.
 */
export function findSortedIndex(
  patchNum: PatchSetNum,
  revisions: RevisionInfo[]
) {
  revisions = revisions || [];
  const findNum = (rev: RevisionInfo) => `${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 -parseInt(`${rangeBase}`, 10);
}
