/**
 * Fetches favicons for all linked domains and saves them locally to public/favicons/.
 * Run before astro build so favicons are served statically instead of via Google S2.
 * Idempotent: skips domains that already have a cached favicon.
 */

import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = fileURLToPath(new URL(".", import.meta.url));
const root = join(__dirname, "..");
const linksPath = join(root, "src/content/links/links.json");
const outDir = join(root, "public/favicons");

function getDomain(url) {
  try {
    return new URL(url).hostname.replace(/^www\./, "");
  } catch {
    return null;
  }
}

function faviconPath(domain) {
  return join(outDir, `${domain}.png`);
}

async function fetchFavicon(domain) {
  const url = `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const buf = await res.arrayBuffer();
  return Buffer.from(buf);
}

async function main() {
  const links = JSON.parse(readFileSync(linksPath, "utf-8"));

  const domains = [
    ...new Set(links.map((l) => getDomain(l.url)).filter(Boolean)),
  ];

  if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });

  let fetched = 0;
  let skipped = 0;

  await Promise.all(
    domains.map(async (domain) => {
      const dest = faviconPath(domain);
      if (existsSync(dest)) {
        skipped++;
        return;
      }
      try {
        const data = await fetchFavicon(domain);
        writeFileSync(dest, data);
        fetched++;
        console.log(`  ✓ ${domain}`);
      } catch (err) {
        console.warn(`  ✗ ${domain}: ${err.message}`);
      }
    }),
  );

  console.log(
    `Favicons: ${fetched} fetched, ${skipped} cached, ${domains.length} total`,
  );
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
