/** Server-only font filesystem helpers. Do not import from client components. */

import fs from "fs/promises";
import path from "path";
import { CURATED_FONTS, SYSTEM_FONT, type CuratedFontKey } from "./fonts";

export function getFontsDir(): string {
  return path.join(process.cwd(), "assets", "fonts");
}

/** Resolve the bundled system (Arimo) font for FFmpeg + preview. */
export function resolveSystemFontPath(weight: "regular" | "bold" = "regular"): string {
  const file = weight === "bold" ? SYSTEM_FONT.boldFile : SYSTEM_FONT.file;
  const safe = file.replace(/[^a-zA-Z0-9._-]/g, "");
  if (safe !== file) throw new Error("Invalid font asset name");
  return path.join(getFontsDir(), safe);
}

/** Resolve a curated font file on disk (must exist under assets/fonts). */
export function resolveCuratedFontPath(
  key: CuratedFontKey,
  weight: "regular" | "bold" = "regular",
): string {
  const meta = CURATED_FONTS.find((f) => f.key === key);
  if (!meta) throw new Error("Unknown font");
  const file =
    weight === "bold" && meta.boldFile ? meta.boldFile : meta.file;
  // Whitelist filename only  never accept user-controlled path segments
  const safe = file.replace(/[^a-zA-Z0-9._-]/g, "");
  if (safe !== file) throw new Error("Invalid font asset name");
  return path.join(getFontsDir(), safe);
}

/**
 * Validate TTF / OTF magic bytes.
 * TTF: 00 01 00 00 | true | typ1
 * OTF: OTTO
 */
export async function assertFontFile(filePath: string): Promise<"ttf" | "otf"> {
  const fh = await fs.open(filePath, "r");
  try {
    const buf = Buffer.alloc(4);
    await fh.read(buf, 0, 4, 0);
    const asStr = buf.toString("ascii");
    if (asStr === "OTTO") return "otf";
    if (asStr === "true" || asStr === "typ1") return "ttf";
    if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00) {
      return "ttf";
    }
    if (asStr === "wOFF" || asStr === "wOF2") {
      throw new Error("WOFF fonts are not supported. Upload a .ttf or .otf file.");
    }
    throw new Error("File is not a valid TTF or OTF font");
  } finally {
    await fh.close();
  }
}
