#!/usr/bin/env bun
// Generates src/lib/templates.data.ts with embedded template file contents.
// Run: bun run templates
import { readdirSync, readFileSync, statSync } from 'fs'
import { extname, join, relative } from 'path'

const BINARY_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot', '.svg'])
const TEMPLATES_DIR = join(import.meta.dir, '..', 'templates')

const binary: Record<string, Record<string, string>> = {}
const shared: Record<string, string> = {}
const templates: Record<string, Record<string, string>> = {}

const isBinary = (path: string) =>
  BINARY_EXTENSIONS.has(extname(path))

function readDir(dir: string): string[] {
  const files: string[] = []
  for (const entry of readdirSync(dir)) {
    const path = join(dir, entry)
    if (statSync(path).isDirectory()) {
      files.push(...readDir(path))
    } else {
      files.push(path)
    }
  }
  return files.sort()
}

// First pass: collect shared files (root level)
for (const entry of readdirSync(TEMPLATES_DIR).sort()) {
  const path = join(TEMPLATES_DIR, entry)
  if (!statSync(path).isDirectory()) {
    shared[entry] = readFileSync(path, 'utf-8')
  }
}

// Second pass: build template maps with shared files folded in
for (const entry of readdirSync(TEMPLATES_DIR).sort()) {
  const path = join(TEMPLATES_DIR, entry)
  if (statSync(path).isDirectory()) {
    templates[entry] = { ...shared }
    binary[entry] = {}
    for (const filePath of readDir(path)) {
      const filename = relative(path, filePath)
      if (isBinary(filePath)) {
        binary[entry]![filename] = readFileSync(filePath).toString('base64')
      } else {
        templates[entry]![filename] = readFileSync(filePath, 'utf-8')
      }
    }
    if (Object.keys(binary[entry]!).length === 0) {
      delete binary[entry]
    }
  }
}

// Generate TypeScript module
const lines: string[] = [
  '// Auto-generated by scripts/embed-templates.ts',
  '// Run `bun run templates` to regenerate',
  '',
  `export const TEMPLATES: Record<string, Record<string, string>> = ${JSON.stringify(templates, null, 2)}`,
  '',
  `export const BINARY: Record<string, Record<string, string>> = ${JSON.stringify(binary, null, 2)}`,
  '',
]

const outPath = join(import.meta.dir, '..', 'src', 'lib', 'templates.data.ts')
await Bun.write(outPath, lines.join('\n'))
console.log(`✓ Embedded templates → ${relative(join(import.meta.dir, '..'), outPath)}`)
