#!/usr/bin/env node
// The admin bundle is embedded in the server binary and served to a household
// LAN, so an accidental dependency or a stray asset landing in dist is a
// regression nobody would otherwise notice: every other gate passes with a
// bundle twice this size. One number, total bytes of dist/assets — not per
// chunk, not gzipped — because the failure being caught is "something big
// arrived", not chunk shape.
//
// This runs from admin/ as part of `npm run build`, before stamp-dist: a failed
// size check must not leave a fresh .src-hash beside an oversized bundle that a
// later Zig build would accept as current.

import { readdirSync, statSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const BUDGET_BYTES = 850_000;

const distDir = join(dirname(dirname(fileURLToPath(import.meta.url))), "dist", "assets");

let entries;
try {
	entries = readdirSync(distDir, { withFileTypes: true });
} catch (err) {
	console.error(`assert-bundle-size: cannot read admin/dist/assets: ${err.message}`);
	process.exit(1);
}

const files = entries
	.filter((entry) => entry.isFile())
	.map((entry) => ({ name: entry.name, bytes: statSync(join(distDir, entry.name)).size }))
	.sort((a, b) => b.bytes - a.bytes);

if (files.length === 0) {
	console.error("assert-bundle-size: no files in admin/dist/assets — did the build emit anything?");
	process.exit(1);
}

const total = files.reduce((sum, file) => sum + file.bytes, 0);
const format = (bytes) => bytes.toLocaleString("en-US");

if (total > BUDGET_BYTES) {
	console.error(
		`assert-bundle-size: admin/dist/assets is ${format(total)} bytes, over the ${format(BUDGET_BYTES)} byte budget.`,
	);
	console.error("Largest chunks:");
	for (const file of files.slice(0, 5)) console.error(`  ${format(file.bytes).padStart(9)}  ${file.name}`);
	console.error("Drop what arrived, or raise the budget in this script with the reason in the changelog.");
	process.exit(1);
}

console.log(
	`admin/dist/assets is ${format(total)} bytes across ${files.length} files, ` +
		`${format(BUDGET_BYTES - total)} under the ${format(BUDGET_BYTES)} byte budget`,
);
