import { getLogger } from "../../../logger.js";
import { NativeSandboxExecutor } from "./NativeSandboxExecutor.js";
import { VercelSandboxExecutor } from "./VercelSandboxExecutor.js";

//#region src/domains/run/tools/SandboxExecutorFactory.ts
const logger = getLogger("SandboxExecutorFactory");
/**
* Factory for creating and managing sandbox executors
* Routes execution to the appropriate sandbox provider (native or Vercel)
*/
var SandboxExecutorFactory = class SandboxExecutorFactory {
	static instance;
	static sessionFactories = /* @__PURE__ */ new Map();
	nativeExecutor = null;
	vercelExecutors = /* @__PURE__ */ new Map();
	constructor() {
		logger.info({}, "SandboxExecutorFactory initialized");
	}
	/**
	* Get singleton instance of SandboxExecutorFactory
	*/
	static getInstance() {
		if (!SandboxExecutorFactory.instance) SandboxExecutorFactory.instance = new SandboxExecutorFactory();
		return SandboxExecutorFactory.instance;
	}
	/**
	* Get a session-scoped instance of SandboxExecutorFactory.
	* Intended to scope Vercel sandbox pooling to a single message/session.
	*/
	static getForSession(sessionId) {
		const existing = SandboxExecutorFactory.sessionFactories.get(sessionId);
		if (existing) return existing;
		const created = new SandboxExecutorFactory();
		SandboxExecutorFactory.sessionFactories.set(sessionId, created);
		return created;
	}
	/**
	* Cleanup and remove a session-scoped SandboxExecutorFactory.
	*/
	static async cleanupSession(sessionId) {
		const factory = SandboxExecutorFactory.sessionFactories.get(sessionId);
		if (!factory) return;
		await factory.cleanup();
		SandboxExecutorFactory.sessionFactories.delete(sessionId);
	}
	/**
	* Execute a function tool using the appropriate sandbox provider
	*/
	async executeFunctionTool(functionId, args, config) {
		const sandboxConfig = config.sandboxConfig;
		if (!sandboxConfig) throw new Error("Sandbox configuration is required for function tool execution");
		if (sandboxConfig.provider === "native") return this.executeInNativeSandbox(functionId, args, config);
		if (sandboxConfig.provider === "vercel") return this.executeInVercelSandbox(functionId, args, config);
		throw new Error(`Unknown sandbox provider: ${sandboxConfig.provider}`);
	}
	/**
	* Execute in native sandbox
	*/
	async executeInNativeSandbox(functionId, args, config) {
		if (!this.nativeExecutor) {
			this.nativeExecutor = new NativeSandboxExecutor();
			logger.info({}, "Native sandbox executor created");
		}
		return this.nativeExecutor.executeFunctionTool(functionId, args, config);
	}
	/**
	* Execute in Vercel sandbox
	*/
	async executeInVercelSandbox(functionId, args, config) {
		const vercelConfig = config.sandboxConfig;
		const configKey = `${vercelConfig.teamId}:${vercelConfig.projectId}`;
		if (!this.vercelExecutors.has(configKey)) {
			const executor$1 = new VercelSandboxExecutor(vercelConfig);
			this.vercelExecutors.set(configKey, executor$1);
			logger.info({
				teamId: vercelConfig.teamId,
				projectId: vercelConfig.projectId
			}, "Vercel sandbox executor created");
		}
		const executor = this.vercelExecutors.get(configKey);
		if (!executor) throw new Error(`Failed to get Vercel executor for config: ${configKey}`);
		const result = await executor.executeFunctionTool(functionId, args, config);
		if (!result.success) throw new Error(result.error || "Vercel sandbox execution failed");
		return result.result;
	}
	/**
	* Clean up all sandbox executors
	*/
	async cleanup() {
		logger.info({}, "Cleaning up sandbox executors");
		if (this.nativeExecutor) {
			await this.nativeExecutor.cleanup();
			this.nativeExecutor = null;
		}
		for (const [key, executor] of this.vercelExecutors.entries()) {
			await executor.cleanup();
			this.vercelExecutors.delete(key);
		}
		logger.info({}, "Sandbox executor cleanup completed");
	}
};

//#endregion
export { SandboxExecutorFactory };