import { createHash } from "node:crypto";
import { readFile, writeFile, readdir } from "node:fs/promises";
import path from "node:path";

const PLACEHOLDER = "__ASSET_VERSION__";
const root = path.resolve(process.argv[2] || process.cwd());
const assetRoots = ["public", "shared"];

async function walk(directory) {
	const entries = await readdir(directory, { withFileTypes: true });
	const files = await Promise.all(
		entries.map((entry) => {
			const target = path.join(directory, entry.name);
			return entry.isDirectory() ? walk(target) : target;
		}),
	);
	return files.flat().sort();
}

const files = (
	await Promise.all(assetRoots.map((directory) => walk(path.join(root, directory))))
).flat();
const sources = await Promise.all(files.map((file) => readFile(file, "utf8")));
const version = createHash("sha256")
	.update(files.map((file, index) => `${path.relative(root, file)}\0${sources[index]}`).join("\0"))
	.digest("hex")
	.slice(0, 16);
let replacements = 0;
await Promise.all(
	files.map(async (file, index) => {
		const source = sources[index];
		const count = source.split(PLACEHOLDER).length - 1;
		if (!count) return;
		replacements += count;
		await writeFile(file, source.replaceAll(PLACEHOLDER, version));
	}),
);
if (!replacements) throw new Error(`No ${PLACEHOLDER} markers found under ${assetRoots.join(", ")}.`);
console.log(`Stamped ${replacements} asset references with version ${version}.`);
