import { createProxyServer } from "./proxy-server.js";

const PROXY_COMMAND_NAME = "genai-proxy";
const PROXY_FLAG_NAME = "genai-proxy";
const DEFAULT_PROXY_PORT = 3000;
export function installGenaiProxyExtension(api, dependencies) {
	let proxyServer = null;
	const buildProxyServer = dependencies?.createProxyServer ?? createProxyServer;
	const ensureProxyServer = (context, port) => {
		if (proxyServer && proxyServer.getPort() === port) {
			return proxyServer;
		}
		if (proxyServer) {
			throw new Error(`Proxy already running on port ${proxyServer.getPort()}`);
		}
		proxyServer = buildProxyServer({
			port,
			modelRegistry: context.modelRegistry,
			onLog: (message) => notifyProxyStatus(context, message, "info"),
		});
		return proxyServer;
	};
	const startProxyFromFlag = async (value, context) => {
		const server = ensureProxyServer(context, resolveProxyPort(value));
		await server.start();
	};
	api.registerFlag(PROXY_FLAG_NAME, {
		description: "Start the GenAI proxy server",
		type: "string",
		allowNoValue: true,
		onStartup: startProxyFromFlag,
	});
	api.registerCommand(PROXY_COMMAND_NAME, {
		description: "Manage the GenAI proxy server",
		handler: async (args, context) => {
			await handleProxyCommand(
				args ?? "",
				context,
				ensureProxyServer,
				() => proxyServer,
				() => {
					proxyServer = null;
				},
			);
		},
	});
}
export function resolveProxyPort(flagValue) {
	if (flagValue === true || flagValue === false || flagValue === undefined) {
		return DEFAULT_PROXY_PORT;
	}
	const port = Number.parseInt(flagValue, 10);
	if (!Number.isFinite(port) || port <= 0 || port > 65535) {
		throw new Error(`Invalid proxy port: ${flagValue}`);
	}
	return port;
}
async function handleProxyCommand(
	rawArgs,
	context,
	ensureProxyServer,
	getProxyServer,
	clearProxyServer,
) {
	const [subcommand = "status", portArg] = rawArgs
		.trim()
		.split(/\s+/)
		.filter((value) => value.length > 0);
	if (subcommand === "start") {
		const existingServer = getProxyServer();
		if (existingServer?.isRunning()) {
			notifyProxyStatus(
				context,
				`Proxy already running on port ${existingServer.getPort()}`,
				"info",
			);
			return;
		}
		const server = ensureProxyServer(
			context,
			resolveProxyPort(portArg === undefined ? true : portArg),
		);
		await server.start();
		return;
	}
	if (subcommand === "stop") {
		const server = getProxyServer();
		if (!server?.isRunning()) {
			notifyProxyStatus(context, "Proxy is not running", "warning");
			return;
		}
		await server.stop();
		clearProxyServer();
		notifyProxyStatus(context, "Proxy stopped", "success");
		return;
	}
	if (subcommand === "status") {
		const server = getProxyServer();
		if (server?.isRunning()) {
			notifyProxyStatus(
				context,
				`Proxy running on port ${server.getPort()}`,
				"info",
			);
			return;
		}
		notifyProxyStatus(context, "Proxy is not running", "info");
		return;
	}
	notifyProxyStatus(
		context,
		"Usage: /genai-proxy start [port] | stop | status",
		"warning",
	);
}
function notifyProxyStatus(context, message, type) {
	if ("ui" in context) {
		context.ui.notify(message, type);
		return;
	}
	process.stderr.write(`[genai-proxy] ${message}\n`);
}
