/**
 * Cluster Manager for SAPPS Backend
 * Enables multi-process handling to utilize all 4 CPU cores
 * Safe implementation - doesn't break existing single-process mode
 */

const cluster = require("cluster");
const os = require("os");

const CPU_CORES = os.cpus().length;

/**
 * Get optimal number of workers based on CPU cores
 * For 4 cores: use 4 workers (1 per core)
 */
function getOptimalWorkers() {
	// Use all available cores, but leave 1 for system
	const workers = Math.max(1, CPU_CORES);
	console.log(`[Cluster] Detected ${CPU_CORES} CPU cores, using ${workers} workers`);
	return workers;
}

/**
 * Check if cluster mode is enabled via environment variable
 */
function isClusterEnabled() {
	return process.env.ENABLE_CLUSTER === "true" || process.env.ENABLE_CLUSTER === "1";
}

/**
 * Start cluster mode - fork workers
 */
function startCluster(app, port) {
	if (!cluster.isMaster) {
		// Worker process - run the app
		return { isWorker: true };
	}

	console.log(`[Cluster] Starting cluster mode with ${getOptimalWorkers()} workers`);

	const numCPUs = getOptimalWorkers();
	const workers = [];

	// Fork workers
	for (let i = 0; i < numCPUs; i++) {
		const worker = cluster.fork({
			WORKER_INDEX: i,
			WORKER_PORT: port,
		});
		workers.push(worker);

		worker.on("message", (message) => {
			// Handle inter-process messages if needed
			console.log(`[Cluster] Worker ${worker.id} message:`, message);
		});
	}

	// Handle worker exit - restart if unexpected
	cluster.on("exit", (worker, code, signal) => {
		console.log(`[Cluster] Worker ${worker.process.pid} died (code: ${code}, signal: ${signal}). Restarting...`);

		// Only restart if not graceful shutdown
		if (code !== 0 && code !== 1) {
			const newWorker = cluster.fork({
				WORKER_INDEX: worker.id - 1,
				WORKER_PORT: port,
			});
			console.log(`[Cluster] Restarted worker with pid: ${newWorker.process.pid}`);
		}
	});

	// Graceful shutdown
	process.on("SIGINT", () => {
		console.log("[Cluster] Received SIGINT, shutting down workers...");
		for (const worker of workers) {
			worker.kill("SIGTERM");
		}
		process.exit(0);
	});

	process.on("SIGTERM", () => {
		console.log("[Cluster] Received SIGTERM, shutting down workers...");
		for (const worker of workers) {
			worker.kill("SIGTERM");
		}
		process.exit(0);
	});

	console.log(`[Cluster] Cluster started successfully with ${numCPUs} workers`);

	return { isMaster: true, workers: workers.length };
}

/**
 * Simple single-process mode (default - backward compatible)
 */
function startSingleProcess(app, port) {
	console.log("[Cluster] Running in single-process mode (default)");
	return app.listen(port, () => {
		console.log(`[Cluster] Server listening on port ${port}`);
	});
}

/**
 * Auto-select mode based on environment
 */
function autoStart(app, port) {
	if (isClusterEnabled()) {
		return startCluster(app, port);
	} else {
		return startSingleProcess(app, port);
	}
}

module.exports = {
	startCluster,
	startSingleProcess,
	autoStart,
	isClusterEnabled,
	getOptimalWorkers,
	CPU_CORES,
};
