// Pack the site's own source for the fifth title card. The fallback has to be
// more than a link to a repository that may not exist yet: this zip is built
// from the same working tree, so anyone can download the pond, unpack it and
// run `npm install && npm run build`.
//
// It deliberately includes the committed audio wasm and the Rust stage patch;
// it excludes node_modules, builds, scratch screenshots, the vendored Rust
// clone and every local credential file.
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
import { basename, dirname, join, relative, resolve, sep } from 'node:path';
import { fileURLToPath } from 'node:url';
import { zipSync } from 'fflate';

const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const output = join(root, 'public', 'quack-source.zip');
const skipDirs = new Set(['node_modules', 'dist', 'temp', '.git', '.wrangler', 'duck-pond']);
const skipFiles = new Set(['quack-source.zip', '.credentials.local.md']);
const entries = [
	'index.html',
	'package.json',
	'package-lock.json',
	'tsconfig.json',
	'vite.config.ts',
	'README.md',
	'LICENSE',
	'.gitignore',
	'src',
	'public',
	'scripts',
	'docs',
	'audio',
];
const files = {};

/** Add one file or directory, skipping generated output and local-only files. */
function add(path) {
	const base = basename(path);
	if (skipDirs.has(base) || skipFiles.has(base) || base.startsWith('.env') || base.startsWith('deploy-')) return;
	const name = relative(root, path).split(sep).join('/');
	if (statSync(path).isDirectory()) {
		for (const child of readdirSync(path)) add(join(path, child));
		return;
	}
	files[name] = readFileSync(path);
}

for (const entry of entries) {
	const path = join(root, entry);
	if (existsSync(path)) add(path);
}

mkdirSync(join(root, 'public'), { recursive: true });
const zip = zipSync(files, { level: 9 });
writeFileSync(output, zip);
console.log(`source zip ${relative(root, output)} (${(zip.length / 1024).toFixed(0)} KiB, ${Object.keys(files).length} files)`);