import { Command } from '@cliffy/command'
import { ensureDir } from '@std/fs'
import { join } from '@std/path'
import { POLY_DIR } from '../shared/paths.ts'
import { listRegions } from '../shared/regions.ts'

const BASE_URL = 'https://download.geofabrik.de'
const RATE_LIMIT_MS = 1000

async function downloadPoly(region: string, force: boolean): Promise<void> {
  const parts = region.split('/')
  const filename = `${parts[parts.length - 1]}.poly`
  const outDir = join(POLY_DIR, ...parts.slice(0, -1))
  const outPath = join(outDir, filename)

  await ensureDir(outDir)

  if (!force && (await Deno.stat(outPath).catch(() => null))) {
    console.log(`Already exists: ${outPath} (skipping)`)
    return
  }

  const url = `${BASE_URL}/${region}.poly`
  const response = await fetch(url)
  if (!response.ok) {
    console.error(`Failed ${url}: ${response.statusText}`)
    return
  }

  const data = await response.arrayBuffer()
  await Deno.writeFile(outPath, new Uint8Array(data))
  console.log(`Saved: ${outPath}`)
}

export const downloadPolyCmd = new Command()
  .name('download:poly')
  .description('Download .poly boundary file(s) from Geofabrik.')
  .arguments('[region:string]')
  .option('--all', 'Download poly files for every region in regions.txt.')
  .option('--force', 'Re-download even if the file already exists.')
  .action(async ({ all, force }, region) => {
    if (all) {
      const regions = await listRegions()
      for (const r of regions) {
        await downloadPoly(r, force ?? false)
        await new Promise((resolve) => setTimeout(resolve, RATE_LIMIT_MS))
      }
    } else if (region) {
      await downloadPoly(region, force ?? false)
    } else {
      console.error('Provide a region slug or use --all.')
      Deno.exit(1)
    }
  })
