#!/usr/bin/env node

const {
	cpSync,
	existsSync,
	mkdirSync,
	readdirSync,
	rmSync,
} = require("node:fs");
const { join, resolve } = require("node:path");

const root = resolve(__dirname, "..");
const webRoot = join(root, "web");
const standaloneRoot = join(webRoot, ".next", "standalone");
const standaloneAppRoot = join(standaloneRoot, "web");
const standaloneNodeModulesRoot = join(standaloneRoot, "node_modules");
const staticRoot = join(webRoot, ".next", "static");
const publicRoot = join(webRoot, "public");
const distWebRoot = join(root, "dist", "web");
const distStandaloneRoot = join(distWebRoot, "standalone");
const sourceNodePtyRoot = join(webRoot, "node_modules", "node-pty");

const COPY_OPTIONS = {
	recursive: true,
	force: true,
	dereference: true,
};

function overlayNodePty(targetRoot) {
	if (!existsSync(sourceNodePtyRoot)) return [];

	const hydrated = [];
	const directTarget = join(targetRoot, "node_modules", "node-pty");
	mkdirSync(join(targetRoot, "node_modules"), { recursive: true });
	cpSync(sourceNodePtyRoot, directTarget, COPY_OPTIONS);
	hydrated.push(directTarget);

	const hashedNodeModulesRoot = join(targetRoot, ".next", "node_modules");
	if (!existsSync(hashedNodeModulesRoot)) return hydrated;

	for (const entry of readdirSync(hashedNodeModulesRoot, {
		withFileTypes: true,
	})) {
		if (!entry.isDirectory() || !entry.name.startsWith("node-pty-")) continue;
		const target = join(hashedNodeModulesRoot, entry.name);
		cpSync(sourceNodePtyRoot, target, COPY_OPTIONS);
		hydrated.push(target);
	}

	return hydrated;
}

if (!existsSync(standaloneAppRoot)) {
	console.error(
		"[forge] Web standalone build not found at web/.next/standalone/web. Run `npm --prefix web run build` first.",
	);
	process.exit(1);
}

rmSync(distWebRoot, { recursive: true, force: true });
mkdirSync(distStandaloneRoot, { recursive: true });

cpSync(standaloneAppRoot, distStandaloneRoot, COPY_OPTIONS);

if (existsSync(standaloneNodeModulesRoot)) {
	cpSync(
		standaloneNodeModulesRoot,
		join(distStandaloneRoot, "node_modules"),
		COPY_OPTIONS,
	);
}

if (existsSync(staticRoot)) {
	mkdirSync(join(distStandaloneRoot, ".next"), { recursive: true });
	cpSync(staticRoot, join(distStandaloneRoot, ".next", "static"), COPY_OPTIONS);
}

if (existsSync(publicRoot)) {
	cpSync(publicRoot, join(distStandaloneRoot, "public"), COPY_OPTIONS);
}

const hydratedTargets = overlayNodePty(distStandaloneRoot);

console.log(`[forge] Staged web standalone host at ${distStandaloneRoot}`);
if (hydratedTargets.length > 0) {
	console.log(
		`[forge] Hydrated node-pty native assets in ${hydratedTargets.length} location(s).`,
	);
}
