import * as github from '@actions/github'
import * as core from '@actions/core'
import * as rest from '@octokit/rest'

/**
 Those are the cancellable event types tht we know about
 */
const CANCELLABLE_EVENT_TYPES = [
  'push',
  'pull_request',
  'workflow_run',
  'schedule',
  'workflow_dispatch'
]

/**
 * Those are different modes for cancelling
 */
enum CancelMode {
  DUPLICATES = 'duplicates',
  ALL_DUPLICATES = 'allDuplicates',
  SELF = 'self',
  FAILED_JOBS = 'failedJobs',
  NAMED_JOBS = 'namedJobs',
  ALL_DUPLICATED_NAMED_JOBS = 'allDuplicatedNamedJobs'
}

/**
 * Stores information about the owner and repository used, as well as octokit object that is used for
 * authentication.
 */
interface RepositoryInfo {
  octokit: github.GitHub
  owner: string
  repo: string
}

/**
 * Stores information about the workflow info that triggered the current workflow.
 */
interface TriggeringRunInfo {
  workflowId: number
  runId: number
  headRepo: string
  headBranch: string
  headSha: string
  eventName: string
  mergeCommitSha: string | null
  pullRequest: rest.PullsListResponseItem | null
}

/**
 * Converts the source of a run object into a string that can be used as map key in maps where we keep
 * arrays of runs per source group
 * @param triggeringRunInfo the object identifying the triggering workflow
 * @returns the unique string id for the source group
 */
function getSourceGroupId(triggeringRunInfo: TriggeringRunInfo): string {
  return (
    `:${triggeringRunInfo.workflowId}:${triggeringRunInfo.headRepo}` +
    `:${triggeringRunInfo.headBranch}:${triggeringRunInfo.eventName}`
  )
}

/**
 * Creates query parameters selecting all runs that share the same source group as we have. This can
 * be used to select duplicates of my own run.
 *
 * @param repositoryInfo - information about the repository used
 * @param status - status of the run that we are querying for
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @return query parameters merged with the listWorkflowRuns criteria
 */
function createListRunsQueryRunsSameSource(
  repositoryInfo: RepositoryInfo,
  status: string,
  triggeringRunInfo: TriggeringRunInfo
): rest.RequestOptions {
  const request = {
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    workflow_id: triggeringRunInfo.workflowId,
    status,
    branch: triggeringRunInfo.headBranch,
    event: triggeringRunInfo.eventName
  }
  return repositoryInfo.octokit.actions.listWorkflowRuns.endpoint.merge(request)
}
/**
 * Creates query parameters selecting only specific run Id.
 * @param repositoryInfo - information about the repository used
 * @param status - status of the run that we are querying for
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @return query parameters merged with the listWorkflowRuns criteria
 */
function createListRunsQuerySpecificRunId(
  repositoryInfo: RepositoryInfo,
  status: string,
  triggeringRunInfo: TriggeringRunInfo
): rest.RequestOptions {
  const request = {
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    workflow_id: triggeringRunInfo.workflowId,
    status,
    // eslint-disable-next-line @typescript-eslint/camelcase
    run_id: triggeringRunInfo.runId.toString()
  }
  return repositoryInfo.octokit.actions.listWorkflowRuns.endpoint.merge(request)
}

/**
 * Creates query parameters selecting all run Ids for specified workflow Id.
 * @param repositoryInfo - information about the repository used
 * @param status - status of the run that we are querying for
 * @param workflowId - Id of the workflow to retrieve
 * @return query parameters merged with the listWorkflowRuns criteria
 */
function createListRunsQueryAllRuns(
  repositoryInfo: RepositoryInfo,
  status: string,
  workflowId: number | string
): rest.RequestOptions {
  const request = {
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    workflow_id: workflowId,
    status
  }
  return repositoryInfo.octokit.actions.listWorkflowRuns.endpoint.merge(request)
}

/**
 * Creates query parameters selecting all jobs for specified run Id.
 * @param repositoryInfo - information about the repository used
 * @param runId - Id of the run to retrieve jobs for
 * @return query parameters merged with the listJobsForWorkflowRun criteria
 */
function createJobsForWorkflowRunQuery(
  repositoryInfo: RepositoryInfo,
  runId: number
): rest.RequestOptions {
  const request = {
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    run_id: runId
  }
  return repositoryInfo.octokit.actions.listJobsForWorkflowRun.endpoint.merge(
    request
  )
}

/**
 * Returns true if the string matches any of the regexps in array of regexps
 * @param stringToMatch string to match
 * @param regexps array of regexp to match the string against
 * @return array of [matched (boolean), [array of matched strings]]
 */
function matchInArray(
  stringToMatch: string,
  regexps: string[]
): [boolean, string[]] {
  let matched = false
  const allMatches: string[] = []
  for (const regexp of regexps) {
    const match = stringToMatch.match(regexp)
    if (match) {
      matched = true
      allMatches.push(match[0])
    }
  }
  return [matched, allMatches]
}

/**
 * Adds workflow run to the array in the map indexed by key.
 * @param key key to use
 * @param runItem run Item to add
 * @param mapOfWorkflowRunCandidates map of workflow runs to add the run item to
 */
function addWorkflowRunToMap(
  key: string,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): void {
  let arrayOfRuns = mapOfWorkflowRunCandidates.get(key)
  if (arrayOfRuns === undefined) {
    arrayOfRuns = []
    mapOfWorkflowRunCandidates.set(key, arrayOfRuns)
  }
  arrayOfRuns.push(runItem)
}

/**
 * Returns true if the runId specified has jobs matching the regexp and optionally checks if those
 * jobs are failed.
 * * If checkIfFailed is False, it returns true if any of the job name for the run match any of the regexps
 * * Id checkIfFailed is True, it returns true if any of the matching jobs have status 'failed'
 * @param repositoryInfo - information about the repository used
 * @param runId - Id of the run to retrieve jobs for
 * @param jobNameRegexps - array of job name regexps
 * @param checkIfFailed - whether to check the 'failed' status of matched jobs
 * @return array of [matched (boolean), array of matches]
 */
async function jobsMatchingNames(
  repositoryInfo: RepositoryInfo,
  runId: number,
  jobNameRegexps: string[],
  checkIfFailed: boolean
): Promise<[boolean, string[]]> {
  const listJobs = createJobsForWorkflowRunQuery(repositoryInfo, runId)
  if (checkIfFailed) {
    core.info(
      `\nChecking if runId ${runId} has job names matching any of the ${jobNameRegexps} that failed\n`
    )
  } else {
    core.info(
      `\nChecking if runId ${runId} has job names matching any of the ${jobNameRegexps}\n`
    )
  }
  const allMatches: string[] = []
  let matched = false
  for await (const item of repositoryInfo.octokit.paginate.iterator(listJobs)) {
    for (const job of item.data) {
      core.info(`    The job name: ${job.name}, Conclusion: ${job.conclusion}`)
      const [jobMatched, jobMatches] = matchInArray(job.name, jobNameRegexps)
      if (jobMatched) {
        allMatches.push(...jobMatches)
        matched = true
        if (checkIfFailed) {
          // Only fail the build if one of the matching jobs fail
          if (job.conclusion === 'failure') {
            core.info(
              `    The Job ${job.name} matches one of the ${jobNameRegexps} regexps and it failed.` +
                ` It will be added to the candidates.`
            )
          } else {
            core.info(
              `    The Job ${job.name} matches one of the ${jobNameRegexps} regexps but it did not fail. ` +
                ` So far, so good.`
            )
          }
        } else {
          // Fail the build if any of the job names match
          core.info(
            `    The Job ${job.name} matches one of the ${jobNameRegexps} regexps. ` +
              `It will be added to the candidates.`
          )
        }
      }
    }
  }
  return [matched, allMatches]
}

/**
 * Retrieves workflowId from the workflow URL.
 * @param workflowUrl workflow URL to retrieve the ID from
 * @return numerical workflow id
 */
function retrieveWorkflowIdFromUrl(workflowUrl: string): number {
  const workflowIdString = workflowUrl.split('/').pop() || ''
  if (!(workflowIdString.length > 0)) {
    throw new Error('Could not resolve workflow')
  }
  return parseInt(workflowIdString)
}

/**
 * Returns workflowId of the runId specified
 * @param repositoryInfo - information about the repository used
 * @param runId - Id of the run to retrieve jobs for
 * @return workflow ID for the run id
 */
async function getWorkflowId(
  repositoryInfo: RepositoryInfo,
  runId: number
): Promise<number> {
  const reply = await repositoryInfo.octokit.actions.getWorkflowRun({
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    run_id: runId
  })
  core.info(`The source run ${runId} is in ${reply.data.workflow_url} workflow`)
  return retrieveWorkflowIdFromUrl(reply.data.workflow_url)
}

/**
 * Returns workflow runs matching the callable adding query criteria
 * @param repositoryInfo - information about the repository used
 * @param statusValues - array of string status values for runs that we are interested at
 * @param cancelMode - which cancel mode the query is about
 * @param createListRunQuery - what is the callable criteria selection
 * @return map of workflow run items indexed by the workflow run number
 */
async function getWorkflowRuns(
  repositoryInfo: RepositoryInfo,
  statusValues: string[],
  cancelMode: CancelMode,
  createListRunQuery: CallableFunction
): Promise<Map<number, rest.ActionsListWorkflowRunsResponseWorkflowRunsItem>> {
  const workflowRuns = new Map<
    number,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem
  >()
  for (const status of statusValues) {
    const listRuns = await createListRunQuery(status)
    for await (const item of repositoryInfo.octokit.paginate.iterator(
      listRuns
    )) {
      // There is some sort of bug where the pagination URLs point to a
      // different endpoint URL which trips up the resulting representation
      // In that case, fallback to the actual REST 'workflow_runs' property
      const elements =
        item.data.length === undefined ? item.data.workflow_runs : item.data
      for (const element of elements) {
        workflowRuns.set(element.run_number, element)
      }
    }
  }
  core.info(`\nFound runs: ${Array.from(workflowRuns).map(t => t[0])}\n`)
  return workflowRuns
}

/**
 * True if the request is candidate for cancelling in case of duplicate deletion
 * @param runItem item to check
 * @param cancelFutureDuplicates whether future duplicates are being cancelled
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param mapOfWorkflowRunCandidates - map of the workflow runs to add candidates to
 * @return true if we determine that the run Id should be cancelled
 */
function checkCandidateForCancellingDuplicate(
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  cancelFutureDuplicates: boolean,
  triggeringRunInfo: TriggeringRunInfo,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): void {
  const runHeadRepo = runItem.head_repository.full_name
  if (
    triggeringRunInfo.headRepo !== undefined &&
    runHeadRepo !== triggeringRunInfo.headRepo
  ) {
    core.info(
      `\nThe run ${runItem.id} is from a different ` +
        `repo: ${runHeadRepo} (expected ${triggeringRunInfo.headRepo}). Not adding as candidate to cancel.\n`
    )
  }
  if (cancelFutureDuplicates) {
    core.info(
      `\nCancel Future Duplicates: Returning run id that might be duplicate or my own run: ${runItem.id}.\n`
    )
    addWorkflowRunToMap(
      getSourceGroupId(triggeringRunInfo),
      runItem,
      mapOfWorkflowRunCandidates
    )
  } else {
    if (runItem.id === triggeringRunInfo.runId) {
      core.info(`\nThis is my own run ${runItem.id}. Not returning myself!\n`)
    } else if (runItem.id > triggeringRunInfo.runId) {
      core.info(
        `\nThe run ${runItem.id} is started later than my own ` +
          `run ${triggeringRunInfo.runId}. Not returning it\n`
      )
    }
    core.info(`\nFound duplicate of my own run: ${runItem.id}.\n`)
  }
}

/**
 * Should the run be candidate for cancelling in SELF cancelling mode?
 * @param runItem run item
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param mapOfWorkflowRunCandidates - map of the workflow runs to add candidates to
 */
function checkCandidateForCancellingSelf(
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  triggeringRunInfo: TriggeringRunInfo,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): void {
  if (runItem.id === triggeringRunInfo.runId) {
    core.info(`\nAdding the "source" run: ${runItem.id} to candidates.\n`)
    addWorkflowRunToMap(
      getSourceGroupId(triggeringRunInfo),
      runItem,
      mapOfWorkflowRunCandidates
    )
  }
}

/**
 * Should the run be candidate for cancelling of all duplicates
 * @param runItem run item
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param mapOfWorkflowRunCandidates - map of the workflow runs to add candidates to
 */
function checkCandidateForAllDuplicates(
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  triggeringRunInfo: TriggeringRunInfo,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): void {
  core.info(`\nAdding the run: ${runItem.id} to candidates.\n`)
  addWorkflowRunToMap(
    getSourceGroupId(triggeringRunInfo),
    runItem,
    mapOfWorkflowRunCandidates
  )
}

/**
 * Should the run is candidate for cancelling in naming job cancelling mode?
 * @param repositoryInfo - information about the repository used
 * @param runItem run item
 * @param jobNamesRegexps array of regexps to match job names against
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param mapOfWorkflowRunCandidates - map of the workflow runs to add candidates to
 * @return true if the run item contains jobs with names matching the pattern
 */
async function checkCandidateForCancellingNamedJobs(
  repositoryInfo: RepositoryInfo,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  jobNamesRegexps: string[],
  triggeringRunInfo: TriggeringRunInfo,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): Promise<void> {
  // Cancel all jobs that have failed jobs (no matter when started)
  const [matched, allMatches] = await jobsMatchingNames(
    repositoryInfo,
    runItem.id,
    jobNamesRegexps,
    false
  )
  if (matched) {
    core.info(
      `\nSome jobs have matching names in ${runItem.id}: ${allMatches}. Adding it candidates.\n`
    )
    addWorkflowRunToMap(
      getSourceGroupId(triggeringRunInfo),
      runItem,
      mapOfWorkflowRunCandidates
    )
  } else {
    core.info(`\nNone of the jobs match name in ${runItem.id}.\n`)
  }
}

/**
 * Should the run is candidate for cancelling in failed job cancelling mode?
 * @param repositoryInfo - information about the repository used
 * @param runItem run item
 * @param jobNamesRegexps array of regexps to match job names against
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param mapOfWorkflowRunCandidates - map of the workflow runs to add candidates to
 * @return true if the run item contains failed jobs with names matching the pattern
 */
async function checkCandidateForCancellingFailedJobs(
  repositoryInfo: RepositoryInfo,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  jobNamesRegexps: string[],
  triggeringRunInfo: TriggeringRunInfo,
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): Promise<void> {
  // Cancel all jobs that have failed jobs (no matter when started)
  const [matched, allMatches] = await jobsMatchingNames(
    repositoryInfo,
    runItem.id,
    jobNamesRegexps,
    true
  )
  if (matched) {
    core.info(
      `\nSome matching named jobs failed in ${runItem.id}: ${allMatches}. Adding it to candidates.\n`
    )
    addWorkflowRunToMap(
      getSourceGroupId(triggeringRunInfo),
      runItem,
      mapOfWorkflowRunCandidates
    )
  } else {
    core.info(
      `\nNone of the matching jobs failed in ${runItem.id}. Not adding as candidate to cancel.\n`
    )
  }
}

/**
 * Checks if the run is candidate for duplicate cancelling of named jobs. It adds it to the map
 * including the match as a key for duplicate detection.
 * @param repositoryInfo - information about the repository used
 * @param runItem - run item
 * @param jobNamesRegexps - array of regexps to match job names against
 * @param mapOfWorkflowRunCandidates - map of runs to update
 */
async function checkCandidateForDuplicateNamedJobs(
  repositoryInfo: RepositoryInfo,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  jobNamesRegexps: string[],
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): Promise<void> {
  const [matched, allMatches] = await jobsMatchingNames(
    repositoryInfo,
    runItem.id,
    jobNamesRegexps,
    false
  )
  if (matched) {
    for (const match of allMatches) {
      // This is the only case where we are not using source group to cancelling candidates but
      // the match of job names
      addWorkflowRunToMap(match, runItem, mapOfWorkflowRunCandidates)
    }
  }
}

/**
 * Determines whether the run is candidate to be cancelled depending on the mode used and add it to the map
 * of workflow names if it is.
 * @param repositoryInfo - information about the repository used
 * @param runItem - run item
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param cancelMode - cancel mode
 * @param cancelFutureDuplicates - whether to cancel future duplicates
 * @param jobNamesRegexps - what are the regexps for job names
 * @param skipEventTypes - which events should be skipped
 * @param mapOfWorkflowRunCandidates - map of workflow runs to add candidates to
 */
async function checkCandidateForCancelling(
  repositoryInfo: RepositoryInfo,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem,
  triggeringRunInfo: TriggeringRunInfo,
  cancelMode: CancelMode,
  cancelFutureDuplicates: boolean,
  jobNamesRegexps: string[],
  skipEventTypes: string[],
  mapOfWorkflowRunCandidates: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >
): Promise<void> {
  if ('completed' === runItem.status.toString()) {
    core.info(
      `\nThe run ${runItem.id} is completed. Not adding as candidate to cancel.\n`
    )
    return
  }
  if (!CANCELLABLE_EVENT_TYPES.includes(runItem.event.toString())) {
    core.info(
      `\nThe run ${runItem.id} is (${runItem.event} event - not ` +
        `in ${CANCELLABLE_EVENT_TYPES}). Not adding as candidate to cancel.\n`
    )
    return
  }
  if (skipEventTypes.includes(runItem.event.toString())) {
    core.info(
      `\nThe run ${runItem.id} is (${runItem.event} event - ` +
        `it is in skipEventTypes ${skipEventTypes}). Not adding as candidate to cancel.\n`
    )
    return
  }
  if (cancelMode === CancelMode.FAILED_JOBS) {
    await checkCandidateForCancellingFailedJobs(
      repositoryInfo,
      runItem,
      jobNamesRegexps,
      triggeringRunInfo,
      mapOfWorkflowRunCandidates
    )
  } else if (cancelMode === CancelMode.NAMED_JOBS) {
    await checkCandidateForCancellingNamedJobs(
      repositoryInfo,
      runItem,
      jobNamesRegexps,
      triggeringRunInfo,
      mapOfWorkflowRunCandidates
    )
  } else if (cancelMode === CancelMode.SELF) {
    checkCandidateForCancellingSelf(
      runItem,
      triggeringRunInfo,
      mapOfWorkflowRunCandidates
    )
  } else if (cancelMode === CancelMode.DUPLICATES) {
    checkCandidateForCancellingDuplicate(
      runItem,
      cancelFutureDuplicates,
      triggeringRunInfo,
      mapOfWorkflowRunCandidates
    )
  } else if (cancelMode === CancelMode.ALL_DUPLICATES) {
    checkCandidateForAllDuplicates(
      runItem,
      triggeringRunInfo,
      mapOfWorkflowRunCandidates
    )
  } else if (cancelMode === CancelMode.ALL_DUPLICATED_NAMED_JOBS) {
    await checkCandidateForDuplicateNamedJobs(
      repositoryInfo,
      runItem,
      jobNamesRegexps,
      mapOfWorkflowRunCandidates
    )
    return
  } else {
    throw Error(`\nWrong cancel mode ${cancelMode}! Please correct it!.\n`)
  }
}

/**
 * Cancels the specified workflow run.
 * @param repositoryInfo - information about the repository used
 * @param runId - run Id to cancel
 */
async function cancelRun(
  repositoryInfo: RepositoryInfo,
  runId: number
): Promise<void> {
  let reply
  try {
    reply = await repositoryInfo.octokit.actions.cancelWorkflowRun({
      owner: repositoryInfo.owner,
      repo: repositoryInfo.repo,
      // eslint-disable-next-line @typescript-eslint/camelcase
      run_id: runId
    })
    core.info(`\nThe run ${runId} cancelled, status = ${reply.status}\n`)
  } catch (error) {
    core.warning(
      `\nCould not cancel run ${runId}: [${error.status}] ${error.message}\n`
    )
  }
}

/**
 * Returns map of workflow run items matching the criteria specified group by workflow run id
 * @param repositoryInfo - information about the repository used
 * @param statusValues - status values we want to check
 * @param cancelMode - cancel mode to use
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @return map of the run items matching grouped by workflow run id
 */
async function getWorkflowRunsMatchingCriteria(
  repositoryInfo: RepositoryInfo,
  statusValues: string[],
  cancelMode: CancelMode,
  triggeringRunInfo: TriggeringRunInfo
): Promise<Map<number, rest.ActionsListWorkflowRunsResponseWorkflowRunsItem>> {
  return await getWorkflowRuns(
    repositoryInfo,
    statusValues,
    cancelMode,
    function(status: string) {
      if (cancelMode === CancelMode.SELF) {
        core.info(
          `\nFinding runs for my own run: Owner: ${repositoryInfo.owner}, Repo: ${repositoryInfo.repo}, ` +
            `Workflow ID:${triggeringRunInfo.workflowId},` +
            `Source Run id: ${triggeringRunInfo.runId}\n`
        )
        return createListRunsQuerySpecificRunId(
          repositoryInfo,
          status,
          triggeringRunInfo
        )
      } else if (
        cancelMode === CancelMode.FAILED_JOBS ||
        cancelMode === CancelMode.NAMED_JOBS ||
        cancelMode === CancelMode.ALL_DUPLICATES ||
        cancelMode === CancelMode.ALL_DUPLICATED_NAMED_JOBS
      ) {
        core.info(
          `\nFinding runs for all runs: Owner: ${repositoryInfo.owner}, Repo: ${repositoryInfo.repo}, ` +
            `Status: ${status} Workflow ID:${triggeringRunInfo.workflowId}\n`
        )
        return createListRunsQueryAllRuns(
          repositoryInfo,
          status,
          triggeringRunInfo.workflowId
        )
      } else if (cancelMode === CancelMode.DUPLICATES) {
        core.info(
          `\nFinding duplicate runs: Owner: ${repositoryInfo.owner}, Repo: ${repositoryInfo.repo}, ` +
            `Status: ${status} Workflow ID:${triggeringRunInfo.workflowId}, ` +
            `Head Branch: ${triggeringRunInfo.headBranch},` +
            `Event name: ${triggeringRunInfo.eventName}\n`
        )
        return createListRunsQueryRunsSameSource(
          repositoryInfo,
          status,
          triggeringRunInfo
        )
      } else {
        throw Error(`\nWrong cancel mode ${cancelMode}! Please correct it.\n`)
      }
    }
  )
}

/**
 * Finds pull request matching its headRepo, headBranch and headSha
 * @param repositoryInfo - information about the repository used
 * @param headRepo - head repository from which Pull Request comes
 * @param headBranch - head branch from which Pull Request comes
 * @param headSha - sha for the head of the incoming Pull request
 */
async function findPullRequest(
  repositoryInfo: RepositoryInfo,
  headRepo: string,
  headBranch: string,
  headSha: string
): Promise<rest.PullsListResponseItem | null> {
  // Finds Pull request for this workflow run
  core.info(
    `\nFinding PR request id for: owner: ${repositoryInfo.owner}, Repo:${repositoryInfo.repo},` +
      ` Head:${headRepo}:${headBranch}.\n`
  )
  const pullRequests = await repositoryInfo.octokit.pulls.list({
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    head: `${headRepo}:${headBranch}`
  })
  for (const pullRequest of pullRequests.data) {
    core.info(
      `\nComparing: ${pullRequest.number} sha: ${pullRequest.head.sha} with expected: ${headSha}.\n`
    )
    if (pullRequest.head.sha === headSha) {
      core.info(`\nFound PR: ${pullRequest.number}\n`)
      return pullRequest
    }
  }
  core.info(`\nCould not find the PR for this build :(\n`)
  return null
}

/**
 * Finds pull request id for the run item.
 * @param repositoryInfo - information about the repository used
 * @param runItem - run Item that the pull request should be found for
 * @return pull request number to notify (or undefined if not found)
 */
async function findPullRequestForRunItem(
  repositoryInfo: RepositoryInfo,
  runItem: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem
): Promise<number | undefined> {
  const pullRequest = await findPullRequest(
    repositoryInfo,
    runItem.head_repository.owner.login,
    runItem.head_branch,
    runItem.head_sha
  )
  if (pullRequest) {
    return pullRequest.number
  }
  return undefined
}

/**
 * Maps found workflow runs into groups - filters out the workflows that are not eligible for cancelling
 * (depends on cancel Mode) and assigns each workflow to groups - where workflow runs from the
 * same group are put together in one array - in a map indexed by the source group id.
 *
 * @param repositoryInfo - information about the repository used
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param cancelMode - cancel mode to use
 * @param cancelFutureDuplicates - whether to cancel future duplicates
 * @param jobNameRegexps - regexps for job names
 * @param skipEventTypes - array of event names to skip
 * @param workflowRuns - map of workflow runs found
 * @parm maps with string key and array of run items as value. The key might be
 *       * source group id (allDuplicates mode)
 *       * matching job name (allDuplicatedMatchingJobNames mode)
 */
async function filterAndMapWorkflowRunsToGroups(
  repositoryInfo: RepositoryInfo,
  triggeringRunInfo: TriggeringRunInfo,
  cancelMode: CancelMode,
  cancelFutureDuplicates: boolean,
  jobNameRegexps: string[],
  skipEventTypes: string[],
  workflowRuns: Map<
    number,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem
  >
): Promise<
  Map<string, rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]>
> {
  const mapOfWorkflowRunCandidates = new Map()
  for (const [key, runItem] of workflowRuns) {
    core.info(
      `\nChecking run number: ${key} RunId: ${runItem.id} Url: ${runItem.url} Status ${runItem.status}` +
        ` Created at ${runItem.created_at}\n`
    )
    await checkCandidateForCancelling(
      repositoryInfo,
      runItem,
      triggeringRunInfo,
      cancelMode,
      cancelFutureDuplicates,
      jobNameRegexps,
      skipEventTypes,
      mapOfWorkflowRunCandidates
    )
  }
  return mapOfWorkflowRunCandidates
}

/**
 * Add specified comment to Pull Request
 * @param repositoryInfo - information about the repository used
 * @param pullRequestNumber - number of pull request
 * @param comment - comment to add
 */
async function addCommentToPullRequest(
  repositoryInfo: RepositoryInfo,
  pullRequestNumber: number,
  comment: string
): Promise<void> {
  core.info(`\nNotifying PR: ${pullRequestNumber} with '${comment}'.\n`)
  await repositoryInfo.octokit.issues.createComment({
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    issue_number: pullRequestNumber,
    body: comment
  })
}

/**
 * Notifies PR about cancelling
 * @param repositoryInfo - information about the repository used
 * @param selfRunId - my own run id
 * @param pullRequestNumber - number of pull request
 * @param reason reason for cancelling
 */
async function notifyPR(
  repositoryInfo: RepositoryInfo,
  selfRunId: number,
  pullRequestNumber: number,
  reason: string
): Promise<void> {
  const selfWorkflowRunUrl =
    `https://github.com/${repositoryInfo.owner}/${repositoryInfo.repo}` +
    `/actions/runs/${selfRunId}`
  await addCommentToPullRequest(
    repositoryInfo,
    pullRequestNumber,
    `[The Workflow run](${selfWorkflowRunUrl}) is cancelling this PR. ${reason}`
  )
}

/**
 * Cancels all runs in the specified group of runs.
 * @param repositoryInfo - information about the repository used
 * @param sortedRunItems - items sorted in descending order (descending order by created_at)
 * @param notifyPRCancel - whether to notify the PR when cancelling
 * @param selfRunId - what is the self run id
 * @param sourceGroupId - what is the source group id
 * @param reason - reason for cancelling
 */
async function cancelAllRunsInTheGroup(
  repositoryInfo: RepositoryInfo,
  sortedRunItems: rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[],
  notifyPRCancel: boolean,
  selfRunId: number,
  sourceGroupId: string,
  reason: string
): Promise<number[]> {
  core.info(
    `\n###### Cancelling runs for ${sourceGroupId} starting from the most recent  ##########\n` +
      `\n     Number of runs to cancel: ${sortedRunItems.length}\n`
  )
  const cancelledRuns: number[] = []
  for (const runItem of sortedRunItems) {
    if (notifyPRCancel && runItem.event === 'pull_request') {
      const pullRequestNumber = await findPullRequestForRunItem(
        repositoryInfo,
        runItem
      )
      if (pullRequestNumber !== undefined) {
        core.info(
          `\nNotifying PR: ${pullRequestNumber} (runItem: ${runItem}) with: ${reason}\n`
        )
        await notifyPR(repositoryInfo, selfRunId, pullRequestNumber, reason)
      }
    }
    core.info(`\nCancelling run: ${runItem}.\n`)
    await cancelRun(repositoryInfo, runItem.id)
    cancelledRuns.push(runItem.id)
  }
  core.info(
    `\n######  Finished cancelling runs for ${sourceGroupId} ##########\n`
  )
  return cancelledRuns
}

/**
 * Cancels found runs per group. It takes all the found groups, sorts them
 * descending according to create date in each of the groups and cancels them in that order -
 * optionally skipping the first found run in each source group in case of duplicate cancelling.
 *
 * @param repositoryInfo - information about the repository used
 * @param mapOfWorkflowRunCandidatesCandidatesToCancel map of all workflow run candidates
 * @param cancelMode - cancel mode
 * @param cancelFutureDuplicates - whether to cancel future duplicates
 * @param notifyPRCancel - whether to notify PRs with comments
 * @param selfRunId - self run Id
 * @param reason - reason for cancelling
 */
async function cancelTheRunsPerGroup(
  repositoryInfo: RepositoryInfo,
  mapOfWorkflowRunCandidatesCandidatesToCancel: Map<
    string,
    rest.ActionsListWorkflowRunsResponseWorkflowRunsItem[]
  >,
  cancelMode: CancelMode,
  cancelFutureDuplicates: boolean,
  notifyPRCancel: boolean,
  selfRunId: number,
  reason: string
): Promise<number[]> {
  const cancelledRuns: number[] = []
  for (const [
    groupId,
    candidatesArray
  ] of mapOfWorkflowRunCandidatesCandidatesToCancel) {
    // Sort from most recent date - this way we always kill current one at the end (if we kill it at all)
    const sortedRunItems = candidatesArray.sort((runItem1, runItem2) =>
      runItem2.created_at.localeCompare(runItem1.created_at)
    )
    if (sortedRunItems.length > 0) {
      if (
        (cancelMode === CancelMode.DUPLICATES && cancelFutureDuplicates) ||
        cancelMode === CancelMode.ALL_DUPLICATES ||
        cancelMode === CancelMode.ALL_DUPLICATED_NAMED_JOBS
      ) {
        core.info(
          `\nSkipping the first run (${sortedRunItems[0].id}) of all the matching ` +
            `duplicates for '${groupId}'. This one we are going to leave in peace!\n`
        )
        sortedRunItems.shift()
      }
      if (sortedRunItems.length === 0) {
        core.info(`\nNo duplicates to cancel for ${groupId}!\n`)
        continue
      }
      cancelledRuns.push(
        ...(await cancelAllRunsInTheGroup(
          repositoryInfo,
          sortedRunItems,
          notifyPRCancel,
          selfRunId,
          groupId,
          reason
        ))
      )
    } else {
      core.info(
        `\n######  There are no runs to cancel for ${groupId} ##########\n`
      )
    }
  }
  return cancelledRuns
}

/**
 * Find and cancels runs based on the criteria chosen.
 * @param repositoryInfo - information about the repository used
 * @param selfRunId - number of own run id
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param cancelMode - cancel mode used
 * @param cancelFutureDuplicates - whether to cancel future duplicates for duplicate cancelling
 * @param notifyPRCancel - whether to notify in PRs about cancelling
 * @param notifyPRMessageStart - whether to notify PRs when the action starts
 * @param jobNameRegexps - array of regular expressions to match hob names in case of named modes
 * @param skipEventTypes - array of event names that should be skipped
 * @param reason - reason for cancelling
 * @return array of canceled workflow run ids
 */
async function findAndCancelRuns(
  repositoryInfo: RepositoryInfo,
  selfRunId: number,
  triggeringRunInfo: TriggeringRunInfo,
  cancelMode: CancelMode,
  cancelFutureDuplicates: boolean,
  notifyPRCancel: boolean,
  notifyPRMessageStart: string,
  jobNameRegexps: string[],
  skipEventTypes: string[],
  reason: string
): Promise<number[]> {
  const statusValues = ['queued', 'in_progress']
  const workflowRuns = await getWorkflowRunsMatchingCriteria(
    repositoryInfo,
    statusValues,
    cancelMode,
    triggeringRunInfo
  )
  const mapOfWorkflowRunCandidatesCandidatesToCancel = await filterAndMapWorkflowRunsToGroups(
    repositoryInfo,
    triggeringRunInfo,
    cancelMode,
    cancelFutureDuplicates,
    jobNameRegexps,
    skipEventTypes,
    workflowRuns
  )
  return await cancelTheRunsPerGroup(
    repositoryInfo,
    mapOfWorkflowRunCandidatesCandidatesToCancel,
    cancelMode,
    cancelFutureDuplicates,
    notifyPRCancel,
    selfRunId,
    reason
  )
}

/**
 * Returns environment variable that is required - throws error if it is not defined.
 * @param key key for the env variable
 * @return value of the env variable
 */
function getRequiredEnv(key: string): string {
  const value = process.env[key]
  if (value === undefined) {
    const message = `${key} was not defined.`
    throw new Error(message)
  }
  return value
}

/**
 * Gets source run using  of the runId - if this is a workflow run, it returns the information about the source run
 * @param repositoryInfo - information about the repository used
 * @param runId - run id of the run to check
 * @return information about the triggering run
 */
async function getTriggeringRunInfo(
  repositoryInfo: RepositoryInfo,
  runId: number
): Promise<TriggeringRunInfo> {
  const reply = await repositoryInfo.octokit.actions.getWorkflowRun({
    owner: repositoryInfo.owner,
    repo: repositoryInfo.repo,
    // eslint-disable-next-line @typescript-eslint/camelcase
    run_id: runId
  })
  const sourceRun = reply.data
  core.info(
    `Source workflow: Head repo: ${sourceRun.head_repository.full_name}, ` +
      `Head branch: ${sourceRun.head_branch} ` +
      `Event: ${sourceRun.event}, Head sha: ${sourceRun.head_sha}, url: ${sourceRun.url}`
  )
  let pullRequest: rest.PullsListResponseItem | null = null
  if (sourceRun.event === 'pull_request') {
    pullRequest = await findPullRequest(
      repositoryInfo,
      sourceRun.head_repository.owner.login,
      sourceRun.head_branch,
      sourceRun.head_sha
    )
  }

  return {
    workflowId: retrieveWorkflowIdFromUrl(reply.data.workflow_url),
    runId,
    headRepo: reply.data.head_repository.full_name,
    headBranch: reply.data.head_branch,
    headSha: reply.data.head_sha,
    mergeCommitSha: pullRequest ? pullRequest.merge_commit_sha : null,
    pullRequest: pullRequest ? pullRequest : null,
    eventName: reply.data.event
  }
}

/**
 * Performs the actual cancelling.
 *
 * @param repositoryInfo - information about the repository used
 * @param selfRunId - number of own run id
 * @param triggeringRunInfo - information about the workflow that triggered the run
 * @param cancelMode - cancel mode used
 * @param cancelFutureDuplicates - whether to cancel future duplicates for duplicate cancelling
 * @param notifyPRCancel - whether to notify in PRs about cancelling
 * @param notifyPRCancelMessage - message to send when cancelling the PR (overrides default message
 *        generated automatically)
 * @param notifyPRMessageStart - whether to notify PRs when the action starts
 * @param jobNameRegexps - array of regular expressions to match hob names in case of named modes
 * @param skipEventTypes - array of event names that should be skipped
 */
async function performCancelJob(
  repositoryInfo: RepositoryInfo,
  selfRunId: number,
  triggeringRunInfo: TriggeringRunInfo,
  cancelMode: CancelMode,
  notifyPRCancel: boolean,
  notifyPRCancelMessage: string,
  notifyPRMessageStart: string,
  jobNameRegexps: string[],
  skipEventTypes: string[],
  cancelFutureDuplicates: boolean
): Promise<number[]> {
  core.info(
    '\n###################################################################################\n'
  )
  core.info(
    `All parameters: owner: ${repositoryInfo.owner}, repo: ${repositoryInfo.repo}, ` +
      `run id: ${triggeringRunInfo.runId}, ` +
      `head repo ${triggeringRunInfo.headRepo}, headBranch: ${triggeringRunInfo.headBranch}, ` +
      `sourceEventName: ${triggeringRunInfo.eventName}, ` +
      `cancelMode: ${cancelMode}, jobNames: ${jobNameRegexps}`
  )
  core.info(
    '\n###################################################################################\n'
  )
  let reason = ''
  if (cancelMode === CancelMode.SELF) {
    core.info(
      `# Cancelling source run: ${triggeringRunInfo.runId} ` +
        `for workflow ${triggeringRunInfo.workflowId}.`
    )
    reason = notifyPRCancelMessage
      ? notifyPRCancelMessage
      : `The job has been cancelled by another workflow.`
  } else if (cancelMode === CancelMode.FAILED_JOBS) {
    core.info(
      `# Cancel all runs for workflow ${triggeringRunInfo.workflowId} ` +
        `where job names matching ${jobNameRegexps} failed.`
    )
    reason = `It has some failed jobs matching ${jobNameRegexps}.`
  } else if (cancelMode === CancelMode.NAMED_JOBS) {
    core.info(
      `# Cancel all runs for workflow ${triggeringRunInfo.workflowId} ` +
        `have job names matching ${jobNameRegexps}.`
    )
    reason = `It has jobs matching ${jobNameRegexps}.`
  } else if (cancelMode === CancelMode.DUPLICATES) {
    core.info(
      `# Cancel duplicate runs for workflow ${triggeringRunInfo.workflowId} ` +
        `for same triggering branch as own run Id.`
    )
    reason = `It is an earlier duplicate of ${triggeringRunInfo.workflowId} run.`
  } else if (cancelMode === CancelMode.ALL_DUPLICATES) {
    core.info(
      `# Cancel all duplicates runs started for workflow ${triggeringRunInfo.workflowId}.`
    )
    reason = `It is an earlier duplicate of ${triggeringRunInfo.workflowId} run.`
  } else if (cancelMode === CancelMode.ALL_DUPLICATED_NAMED_JOBS) {
    core.info(
      `# Cancel all duplicate named jobs matching the patterns ${jobNameRegexps}.`
    )
    reason = `It is an earlier duplicate of ${triggeringRunInfo.workflowId} run.`
  } else {
    throw Error(`Wrong cancel mode ${cancelMode}! Please correct it.`)
  }
  core.info(
    '\n###################################################################################\n'
  )

  return await findAndCancelRuns(
    repositoryInfo,
    selfRunId,
    triggeringRunInfo,
    cancelMode,
    cancelFutureDuplicates,
    notifyPRCancel,
    notifyPRMessageStart,
    jobNameRegexps,
    skipEventTypes,
    reason
  )
}

/**
 * Retrieves information about source workflow Id. Either from the current event or from the workflow
 * nme specified. If the file name is not specified, the workflow to act on is either set to self event
 * or in case of workflow_run event - to the workflow id that triggered the 'workflow_run' event.
 *
 * @param repositoryInfo - information about the repository used
 * @param workflowFileName - optional workflow file name
 * @param runId - run id of the workflow
 * @param selfRunId - self run id
 * @return workflow id that is associate with the workflow we are going to act on.
 */
async function retrieveWorkflowId(
  repositoryInfo: RepositoryInfo,
  workflowFileName: string | null,
  runId: number,
  selfRunId: number
): Promise<string | number> {
  let workflowId
  if (workflowFileName) {
    workflowId = workflowFileName
    core.info(
      `\nFinding runs for another workflow found by ${workflowFileName} name: ${workflowId}\n`
    )
  } else {
    workflowId = await getWorkflowId(repositoryInfo, runId)
    if (runId === selfRunId) {
      core.info(`\nFinding runs for my own workflow ${workflowId}\n`)
    } else {
      core.info(`\nFinding runs for source workflow ${workflowId}\n`)
    }
  }
  return workflowId
}
/**
 * Sets output but also prints the output value in the logs.
 *
 * @param name name of the output
 * @param value value of the output
 */
function verboseOutput(name: string, value: string): void {
  core.info(`Setting output: ${name}: ${value}`)
  core.setOutput(name, value)
}

/**
 * Performs sanity check of the parameters passed. Some of the parameter combinations do not work so they
 * are verified and in case od unexpected combination found, approrpriate error is raised.
 *
 * @param eventName - name of the event to act on
 * @param runId - run id of the triggering event
 * @param selfRunId - our own run id
 * @param cancelMode - cancel mode used
 * @param cancelFutureDuplicates - whether future duplicate cancelling is enabled
 * @param jobNameRegexps - array of regular expression of job names
 */
function performSanityChecks(
  eventName: string,
  runId: number,
  selfRunId: number,
  cancelMode: CancelMode,
  cancelFutureDuplicates: boolean,
  jobNameRegexps: string[]
): void {
  if (
    eventName === 'workflow_run' &&
    runId === selfRunId &&
    cancelMode === CancelMode.DUPLICATES
  ) {
    throw Error(
      `You cannot run "workflow_run" in ${cancelMode} cancelMode without "sourceId" input.` +
        'It will likely not work as you intended - it will cancel runs which are not duplicates!' +
        'See the docs for details.'
    )
  }

  if (
    jobNameRegexps.length > 0 &&
    [
      CancelMode.DUPLICATES,
      CancelMode.SELF,
      CancelMode.ALL_DUPLICATES
    ].includes(cancelMode)
  ) {
    throw Error(
      `You cannot specify jobNamesRegexps on ${cancelMode} cancelMode.`
    )
  }

  if (
    jobNameRegexps.length === 0 &&
    [
      CancelMode.NAMED_JOBS,
      CancelMode.FAILED_JOBS,
      CancelMode.ALL_DUPLICATED_NAMED_JOBS
    ].includes(cancelMode)
  ) {
    throw Error(`You must specify jobNamesRegexps on ${cancelMode} cancelMode.`)
  }

  if (
    (cancelMode === CancelMode.ALL_DUPLICATES ||
      cancelMode === CancelMode.ALL_DUPLICATED_NAMED_JOBS) &&
    !cancelFutureDuplicates
  ) {
    throw Error(
      `The  ${cancelMode} cancelMode has to have cancelFutureDuplicates set to true.`
    )
  }
}

/**
 * Produces basic outputs for the action. This does not include cancelled workflow run id - those are
 * set after cancelling is done.
 *
 * @param triggeringRunInfo
 */
function produceBasicOutputs(triggeringRunInfo: TriggeringRunInfo): void {
  verboseOutput('sourceHeadRepo', triggeringRunInfo.headRepo)
  verboseOutput('sourceHeadBranch', triggeringRunInfo.headBranch)
  verboseOutput('sourceHeadSha', triggeringRunInfo.headSha)
  verboseOutput('sourceEvent', triggeringRunInfo.eventName)
  verboseOutput(
    'pullRequestNumber',
    triggeringRunInfo.pullRequest
      ? triggeringRunInfo.pullRequest.number.toString()
      : ''
  )
  verboseOutput(
    'mergeCommitSha',
    triggeringRunInfo.mergeCommitSha ? triggeringRunInfo.mergeCommitSha : ''
  )
  verboseOutput(
    'targetCommitSha',
    triggeringRunInfo.mergeCommitSha
      ? triggeringRunInfo.mergeCommitSha
      : triggeringRunInfo.headSha
  )
}

/**
 * Notifies the PR that the action has started.
 *
 * @param repositoryInfo information about the repository
 * @param triggeringRunInfo information about the triggering workflow
 * @param selfRunId self run id
 * @param notifyPRMessageStart whether to notify about the start of the action
 */
async function notifyActionStart(
  repositoryInfo: RepositoryInfo,
  triggeringRunInfo: TriggeringRunInfo,
  selfRunId: number,
  notifyPRMessageStart: string
): Promise<void> {
  if (notifyPRMessageStart && triggeringRunInfo.pullRequest) {
    const selfWorkflowRunUrl =
      `https://github.com/${repositoryInfo.owner}/${repositoryInfo.repo}` +
      `/actions/runs/${selfRunId}`
    await repositoryInfo.octokit.issues.createComment({
      owner: repositoryInfo.owner,
      repo: repositoryInfo.repo,
      // eslint-disable-next-line @typescript-eslint/camelcase
      issue_number: triggeringRunInfo.pullRequest.number,
      body: `${notifyPRMessageStart} [The workflow run](${selfWorkflowRunUrl})`
    })
  }
}

/**
 * Main run method that does everything :)
 */
async function run(): Promise<void> {
  const token = core.getInput('token', {required: true})
  const octokit = new github.GitHub(token)
  const selfRunId = parseInt(getRequiredEnv('GITHUB_RUN_ID'))
  const repository = getRequiredEnv('GITHUB_REPOSITORY')
  const eventName = getRequiredEnv('GITHUB_EVENT_NAME')
  const cancelMode =
    (core.getInput('cancelMode') as CancelMode) || CancelMode.DUPLICATES
  const notifyPRCancel =
    (core.getInput('notifyPRCancel') || 'false').toLowerCase() === 'true'
  const notifyPRCancelMessage = core.getInput('notifyPRCancelMessage')
  const notifyPRMessageStart = core.getInput('notifyPRMessageStart')
  const sourceRunId = parseInt(core.getInput('sourceRunId')) || selfRunId
  const jobNameRegexpsString = core.getInput('jobNameRegexps')
  const cancelFutureDuplicates =
    (core.getInput('cancelFutureDuplicates') || 'true').toLowerCase() === 'true'
  const jobNameRegexps = jobNameRegexpsString
    ? JSON.parse(jobNameRegexpsString)
    : []

  const skipEventTypesString = core.getInput('skipEventTypes')
  const skipEventTypes = skipEventTypesString
    ? JSON.parse(skipEventTypesString)
    : []
  const workflowFileName = core.getInput('workflowFileName')

  const [owner, repo] = repository.split('/')

  const repositoryInfo: RepositoryInfo = {
    octokit,
    owner,
    repo
  }
  core.info(
    `\nGetting workflow id for source run id: ${sourceRunId}, owner: ${owner}, repo: ${repo},` +
      ` skipEventTypes: ${skipEventTypes}\n`
  )
  const sourceWorkflowId = await retrieveWorkflowId(
    repositoryInfo,
    workflowFileName,
    sourceRunId,
    selfRunId
  )

  performSanityChecks(
    eventName,
    sourceRunId,
    selfRunId,
    cancelMode,
    cancelFutureDuplicates,
    jobNameRegexps
  )

  core.info(
    `Repository: ${repository}, Owner: ${owner}, Repo: ${repo}, ` +
      `Event name: ${eventName}, CancelMode: ${cancelMode}, ` +
      `sourceWorkflowId: ${sourceWorkflowId}, sourceRunId: ${sourceRunId}, selfRunId: ${selfRunId}, ` +
      `jobNames: ${jobNameRegexps}`
  )

  const triggeringRunInfo = await getTriggeringRunInfo(
    repositoryInfo,
    sourceRunId
  )
  produceBasicOutputs(triggeringRunInfo)

  await notifyActionStart(
    repositoryInfo,
    triggeringRunInfo,
    selfRunId,
    notifyPRMessageStart
  )

  const cancelledRuns = await performCancelJob(
    repositoryInfo,
    selfRunId,
    triggeringRunInfo,
    cancelMode,
    notifyPRCancel,
    notifyPRCancelMessage,
    notifyPRMessageStart,
    jobNameRegexps,
    skipEventTypes,
    cancelFutureDuplicates
  )

  verboseOutput('cancelledRuns', JSON.stringify(cancelledRuns))
}

run()
  .then(() =>
    core.info('\n############### Cancel complete ##################\n')
  )
  .catch(e => core.setFailed(e.message))
