/**
 * Self-host the @imgly/background-removal model + wasm assets.
 *
 * @imgly/background-removal is AGPL-3.0. By default it streams its ONNX model
 * and onnxruntime-web wasm binaries from staticimgly.com at runtime. To keep
 * Plimi's privacy promise (nothing leaves the user's browser, no third-party
 * fetches), we mirror the *version-matched* asset bundle into `public/imgly/`
 * and point the library at our own origin via `config.publicPath`.
 *
 * The assets are large (~300MB across all model variants) so they are NOT
 * committed to git — this script is run on `predev` / `prebuild` and is
 * idempotent: it only downloads chunks that are missing.
 */
import { mkdir, readFile, writeFile, stat } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import path from "node:path";

const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const OUT_DIR = path.join(ROOT, "public", "imgly");

// Keep the data version in lock-step with the installed library version,
// otherwise the resources.json format / model keys won't match the runtime.
const { version } = JSON.parse(
  await readFile(
    path.join(ROOT, "node_modules/@imgly/background-removal/package.json"),
    "utf8"
  )
);
const BASE = `https://staticimgly.com/@imgly/background-removal-data/${version}/dist/`;

async function exists(p) {
  try {
    await stat(p);
    return true;
  } catch {
    return false;
  }
}

async function download(url, dest) {
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
  }
  const buf = Buffer.from(await res.arrayBuffer());
  await writeFile(dest, buf);
  return buf.length;
}

async function main() {
  await mkdir(OUT_DIR, { recursive: true });

  console.log(`[imgly] Mirroring background-removal assets v${version}`);
  const resourcesPath = path.join(OUT_DIR, "resources.json");
  await download(new URL("resources.json", BASE).toString(), resourcesPath);

  const resources = JSON.parse(await readFile(resourcesPath, "utf8"));
  const chunkNames = new Set();
  for (const entry of Object.values(resources)) {
    for (const chunk of entry.chunks ?? []) chunkNames.add(chunk.name);
  }

  let downloaded = 0;
  let skipped = 0;
  let bytes = 0;
  for (const name of chunkNames) {
    const dest = path.join(OUT_DIR, name);
    if (await exists(dest)) {
      skipped++;
      continue;
    }
    bytes += await download(new URL(name, BASE).toString(), dest);
    downloaded++;
    if (downloaded % 10 === 0) {
      console.log(`[imgly]   ${downloaded} chunks downloaded...`);
    }
  }

  console.log(
    `[imgly] Done: ${downloaded} downloaded, ${skipped} cached ` +
      `(${(bytes / 1024 / 1024).toFixed(1)} MB new) → public/imgly/`
  );
}

main().catch((err) => {
  console.error("[imgly] Asset mirror failed:", err);
  process.exit(1);
});
