const require_chunk = require('./chunk-CUT6urMc.cjs');
const node_path = require_chunk.__toESM(require("node:path"));
const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
const node_child_process = require_chunk.__toESM(require("node:child_process"));

//#region src/build/bundler.ts
/**
* Banner to inject into ESM bundle for CJS compatibility.
* Creates a `require` function using Node's createRequire for packages
* that internally use CommonJS require() for Node builtins.
*/
const ESM_CJS_COMPAT_BANNER = "import { createRequire } from \"module\"; const require = createRequire(import.meta.url);";
/**
* Collect all required environment variables from constructs.
* Uses the SnifferEnvironmentParser to detect which env vars each service needs.
*
* @param constructs - Array of constructs to analyze
* @returns Deduplicated array of required environment variable names
*/
async function collectRequiredEnvVars(constructs) {
	const allEnvVars = /* @__PURE__ */ new Set();
	for (const construct of constructs) {
		const envVars = await construct.getEnvironment();
		envVars.forEach((v) => allEnvVars.add(v));
	}
	return Array.from(allEnvVars).sort();
}
/**
* Bundle the server application using esbuild.
* Creates a fully standalone bundle with all dependencies included.
*
* @param options - Bundle configuration options
* @returns Bundle result with output path and optional master key
*/
/** Default env var values for docker compose services */
const DOCKER_SERVICE_ENV_VARS = {
	postgres: { DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/app" },
	redis: { REDIS_URL: "redis://redis:6379" },
	rabbitmq: { RABBITMQ_URL: "amqp://rabbitmq:5672" }
};
async function bundleServer(options) {
	const { entryPoint, outputDir, minify, sourcemap, external, stage, constructs, dockerServices } = options;
	await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
	const mjsOutput = (0, node_path.join)(outputDir, "server.mjs");
	const args = [
		"npx",
		"esbuild",
		entryPoint,
		"--bundle",
		"--platform=node",
		"--target=node22",
		"--format=esm",
		`--outfile=${mjsOutput}`,
		"--packages=bundle",
		`--banner:js=${ESM_CJS_COMPAT_BANNER}`
	];
	if (minify) args.push("--minify");
	if (sourcemap) args.push("--sourcemap");
	for (const ext of external) args.push(`--external:${ext}`);
	let masterKey;
	if (stage) {
		const { readStageSecrets, toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets, writeStageSecrets } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
		const { encryptSecrets, generateDefineOptions } = await Promise.resolve().then(() => require("./encryption-CipsS0KW.cjs"));
		let secrets = await readStageSecrets(stage);
		if (!secrets) {
			console.log(`  Initializing secrets for stage "${stage}"...`);
			secrets = initStageSecrets(stage);
			await writeStageSecrets(secrets);
			console.log(`  ✓ Created .gkm/secrets/${stage}.json`);
		}
		if (dockerServices) {
			for (const [service, enabled] of Object.entries(dockerServices)) if (enabled && DOCKER_SERVICE_ENV_VARS[service]) for (const [envVar, defaultValue] of Object.entries(DOCKER_SERVICE_ENV_VARS[service])) {
				const urlKey = envVar;
				if (!secrets.urls[urlKey] && !secrets.custom[envVar]) {
					secrets.urls[urlKey] = defaultValue;
					console.log(`  Auto-populated ${envVar} from docker compose`);
				}
			}
		}
		if (constructs && constructs.length > 0) {
			console.log("  Analyzing environment variable requirements...");
			const requiredVars = await collectRequiredEnvVars(constructs);
			if (requiredVars.length > 0) {
				const validation = validateEnvironmentVariables(requiredVars, secrets);
				if (!validation.valid) {
					const errorMessage = [
						`Missing environment variables for stage "${stage}":`,
						"",
						...validation.missing.map((v) => `  ❌ ${v}`),
						"",
						"To fix this, either:",
						`  1. Add the missing variables to .gkm/secrets/${stage}.json using:`,
						`     gkm secrets:set <KEY> <VALUE> --stage ${stage}`,
						"",
						`  2. Or import from a JSON file:`,
						`     gkm secrets:import secrets.json --stage ${stage}`,
						"",
						"Required variables:",
						...validation.required.map((v) => validation.missing.includes(v) ? `  ❌ ${v}` : `  ✓ ${v}`)
					].join("\n");
					throw new Error(errorMessage);
				}
				console.log(`  ✓ All ${requiredVars.length} required environment variables found`);
			}
		}
		const embeddable = toEmbeddableSecrets(secrets);
		const encrypted = encryptSecrets(embeddable);
		masterKey = encrypted.masterKey;
		const defines = generateDefineOptions(encrypted);
		for (const [key, value] of Object.entries(defines)) args.push(`--define:${key}=${JSON.stringify(value)}`);
		console.log(`  Secrets encrypted for stage "${stage}"`);
	}
	try {
		const [cmd, ...cmdArgs] = args;
		const result = (0, node_child_process.spawnSync)(cmd, cmdArgs, {
			cwd: process.cwd(),
			stdio: "inherit",
			shell: process.platform === "win32"
		});
		if (result.error) throw result.error;
		if (result.status !== 0) throw new Error(`esbuild exited with code ${result.status}`);
		const { readFile } = await import("node:fs/promises");
		const content = await readFile(mjsOutput, "utf-8");
		if (!content.startsWith("#!")) await (0, node_fs_promises.writeFile)(mjsOutput, `#!/usr/bin/env node\n${content}`);
	} catch (error) {
		throw new Error(`Failed to bundle server: ${error instanceof Error ? error.message : "Unknown error"}`);
	}
	return {
		outputPath: mjsOutput,
		masterKey
	};
}

//#endregion
exports.bundleServer = bundleServer;
//# sourceMappingURL=bundler-BG6P249p.cjs.map