const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
const require_a2a_mock = require('./a2a-mock.cjs');
const require_agui_handler = require('./agui-handler.cjs');
const require_logger = require('./logger.cjs');
const require_agui_mock = require('./agui-mock.cjs');
const require_llmock = require('./llmock.cjs');
const require_mcp_mock = require('./mcp-mock.cjs');
const require_vector_mock = require('./vector-mock.cjs');
let node_fs = require("node:fs");
node_fs = require_runtime.__toESM(node_fs);
let node_path = require("node:path");
node_path = require_runtime.__toESM(node_path);

//#region src/config-loader.ts
function loadConfig(configPath) {
	const raw = node_fs.readFileSync(configPath, "utf-8");
	return JSON.parse(raw);
}
async function startFromConfig(config, overrides) {
	const logger = new require_logger.Logger("info");
	let replaySpeed = config.llm?.replaySpeed;
	if (replaySpeed != null && (!Number.isFinite(replaySpeed) || replaySpeed <= 0)) {
		logger.warn(`llm.replaySpeed must be a positive number, got ${replaySpeed}. Ignoring.`);
		replaySpeed = void 0;
	}
	const llmock = new require_llmock.LLMock({
		port: overrides?.port ?? config.port ?? 0,
		host: overrides?.host ?? config.host ?? "127.0.0.1",
		latency: config.llm?.latency,
		chunkSize: config.llm?.chunkSize,
		replaySpeed,
		logLevel: config.llm?.logLevel,
		chaos: config.llm?.chaos,
		record: config.llm?.record,
		metrics: config.metrics,
		strict: config.strict
	});
	if (config.llm?.fixtures) {
		const fixturePath = node_path.resolve(config.llm.fixtures);
		if (node_fs.statSync(fixturePath).isDirectory()) llmock.loadFixtureDir(fixturePath);
		else llmock.loadFixtureFile(fixturePath);
	}
	if (config.mcp) {
		const mcpConfig = config.mcp;
		const mcp = new require_mcp_mock.MCPMock({ serverInfo: mcpConfig.serverInfo });
		if (mcpConfig.tools) for (const tool of mcpConfig.tools) {
			const { result, ...def } = tool;
			mcp.addTool(def);
			if (result !== void 0) mcp.onToolCall(def.name, () => result);
		}
		if (mcpConfig.resources) for (const res of mcpConfig.resources) mcp.addResource({
			uri: res.uri,
			name: res.name,
			mimeType: res.mimeType,
			description: res.description
		}, res.text !== void 0 || res.blob !== void 0 ? {
			text: res.text,
			blob: res.blob,
			mimeType: res.mimeType
		} : void 0);
		if (mcpConfig.prompts) for (const prompt of mcpConfig.prompts) {
			const { result, ...def } = prompt;
			if (result) mcp.addPrompt(def, () => result);
			else mcp.addPrompt(def);
		}
		const mcpPath = mcpConfig.path ?? "/mcp";
		llmock.mount(mcpPath, mcp);
		logger.info(`MCPMock mounted at ${mcpPath}`);
	}
	if (config.a2a) {
		const a2aConfig = config.a2a;
		const a2a = new require_a2a_mock.A2AMock();
		if (a2aConfig.agents) for (const agentConfig of a2aConfig.agents) {
			const { messages, tasks, streamingTasks, ...def } = agentConfig;
			a2a.registerAgent(def);
			if (messages) for (const m of messages) a2a.onMessage(def.name, m.pattern, m.parts ?? [{ text: "" }]);
			if (tasks) for (const t of tasks) a2a.onTask(def.name, t.pattern, t.artifacts ?? []);
			if (streamingTasks) for (const s of streamingTasks) a2a.onStreamingTask(def.name, s.pattern, s.events ?? [], s.delayMs);
		}
		const a2aPath = a2aConfig.path ?? "/a2a";
		llmock.mount(a2aPath, a2a);
		logger.info(`A2AMock mounted at ${a2aPath}`);
	}
	if (config.agui) {
		const aguiConfig = config.agui;
		const agui = new require_agui_mock.AGUIMock();
		if (aguiConfig.fixtures) for (const f of aguiConfig.fixtures) {
			if (f.match.toolCallId && f.text && !f.events) logger.warn(`AG-UI fixture uses text shorthand with toolCallId — text shorthand ignores toolCallId matching; use events[] instead (match: ${JSON.stringify(f.match)})`);
			if (f.text) if (f.match.message !== void 0) agui.onMessage(f.match.message, f.text, { delayMs: f.delayMs });
			else agui.addFixture({
				match: {
					toolCallId: f.match.toolCallId,
					toolName: f.match.toolName,
					stateKey: f.match.stateKey
				},
				events: require_agui_handler.buildTextResponse(f.text),
				delayMs: f.delayMs
			});
			else if (f.events) agui.addFixture({
				match: {
					message: f.match.message,
					toolCallId: f.match.toolCallId,
					toolName: f.match.toolName,
					stateKey: f.match.stateKey
				},
				events: f.events,
				delayMs: f.delayMs
			});
			else logger.warn(`AG-UI fixture has neither text nor events — it will be skipped (match: ${JSON.stringify(f.match)})`);
		}
		const aguiPath = aguiConfig.path ?? "/agui";
		llmock.mount(aguiPath, agui);
		logger.info(`AGUIMock mounted at ${aguiPath}`);
	}
	if (config.vector) {
		const vectorConfig = config.vector;
		const vector = new require_vector_mock.VectorMock();
		if (vectorConfig.collections) for (const col of vectorConfig.collections) {
			vector.addCollection(col.name, { dimension: col.dimension });
			if (col.vectors && col.vectors.length > 0) vector.upsert(col.name, col.vectors);
			if (col.queryResults) vector.onQuery(col.name, col.queryResults);
		}
		const vectorPath = vectorConfig.path ?? "/vector";
		llmock.mount(vectorPath, vector);
		logger.info(`VectorMock mounted at ${vectorPath}`);
	}
	if (config.services) {
		if (config.services.search) {
			llmock.onSearch(/.*/, []);
			logger.info("Search service enabled with default empty results");
		}
		if (config.services.rerank) {
			llmock.onRerank(/.*/, []);
			logger.info("Rerank service enabled with default empty results");
		}
		if (config.services.moderate) {
			llmock.onModerate(/.*/, {
				flagged: false,
				categories: {}
			});
			logger.info("Moderation service enabled with default unflagged results");
		}
	}
	return {
		llmock,
		url: await llmock.start()
	};
}

//#endregion
exports.loadConfig = loadConfig;
exports.startFromConfig = startFromConfig;
//# sourceMappingURL=config-loader.cjs.map