import { type Repository } from "./dataTypes.ts"

type FlatPatchRecord = {
  commit: ReturnType<Repository['commits']['get']>,
  repoName: string,
  refName: string,
  type: "branch" | "tag",
}

let cachedFlatPatches: Array<FlatPatchRecord> | null = null

export default async (repos: Array<Repository>)
  : Promise<Array<FlatPatchRecord>> => {
  if (cachedFlatPatches !== null) { return cachedFlatPatches }

  const itemsForRef: (
    ref: Repository['tags'][0], refType: 'branch' | 'tag', repo: Repository
  ) => Array<FlatPatchRecord> = (ref, refType, repo) => {
    const flatPatches: Array<FlatPatchRecord> = []
    let currentCommit: ReturnType<Repository['commits']['get']> | undefined = repo.commits.get(ref.sha)

    while (currentCommit !== undefined) {
      flatPatches.push({
        type: refType,
        commit: currentCommit,
        repoName: repo.name,
        refName: ref.name
      })

      currentCommit = repo.commits.get(currentCommit.parent)
    }

    return flatPatches
  }



  cachedFlatPatches = repos.flatMap((repo) => {
    const branches = repo.branches.flatMap(branch => itemsForRef(branch, 'branch', repo))

    const tags = repo.tags.flatMap(tag => itemsForRef(tag, 'tag', repo))

    return [...branches, ...tags]
  })

  return cachedFlatPatches
}
