import { join } from "node:path"

type BuildRouteOptions = {
  distDir: string
  routeName: string
  filepath: string
  force?: boolean
}

const cache = new Map<string, boolean>()
export const buildRoute = async ({ distDir, routeName, filepath, force = false }: BuildRouteOptions) => {
  if (!force && !(await needsBuild(routeName, distDir))) {
    return
  }

  const scriptPath = join(import.meta.dirname, "../scripts/build.ts")

  const proc = Bun.spawn({
    cmd: ["bun", "run", scriptPath, distDir, routeName, filepath],
    stdout: "pipe",
    stderr: "pipe",
  })

  const exitCode = await proc.exited

  if (exitCode !== 0) {
    const stderr = await new Response(proc.stderr).text()
    throw new Error(`Build process failed with exit code ${exitCode}: ${stderr}`)
  } else {
    cache.set(distDir + routeName, true)
  }
}

// In production I want to limit the number of times we build routes, so I only build it if it doesn't exist or if the cache is not set
// The cache is so that when we deploy it will always rebuild the routes.
const needsBuild = async (routeName: string, distDir: string) => {
  if (process.env.NODE_ENV !== "production") {
    return true
  }

  try {
    const outputPath = join(distDir, routeName + ".js")
    const exists = await Bun.file(outputPath).exists()
    const inCache = cache.get(distDir + routeName)

    return !exists || !inCache
  } catch (error) {
    return true
  }
}
