import runDbClient_default from "../../../data/db/runDbClient.js";
import { ContextResolver } from "./ContextResolver.js";
import { getConversation, getLogger, getTracer, setSpanWithError, updateConversation } from "@inkeep/agents-core";
import { SpanStatusCode } from "@opentelemetry/api";

//#region src/domains/run/context/context.ts
const logger = getLogger("context");
const tracer = getTracer("context");
async function determineContextTrigger(tenantId, projectId, conversationId) {
	const conversation = await getConversation(runDbClient_default)({
		scopes: {
			tenantId,
			projectId
		},
		conversationId
	});
	if (!conversation || !conversation.lastContextResolution) return "initialization";
	return "invocation";
}
async function handleContextConfigChange(executionContext, conversationId, newContextConfigId, credentialStores) {
	const { tenantId, projectId, agentId } = executionContext;
	const conversation = await getConversation(runDbClient_default)({
		scopes: {
			tenantId,
			projectId
		},
		conversationId
	});
	if (!conversation) return;
	if (conversation.lastContextResolution) {
		await new ContextResolver(executionContext, credentialStores).clearCache(tenantId, projectId, conversationId);
		logger.info({
			conversationId,
			agentId,
			contextConfigId: newContextConfigId
		}, "Potential context config change for existing conversation, cache cleared");
	}
}
async function handleContextResolution({ executionContext, conversationId, headers: headers$1, credentialStores }) {
	return tracer.startActiveSpan("context.handle_context_resolution", { attributes: { "context.headers_keys": Object.keys(headers$1) } }, async (parentSpan) => {
		const { tenantId, projectId, agentId, project } = executionContext;
		const agent = project.agents[agentId];
		let trigger;
		try {
			const contextConfig = agent.contextConfig;
			if (!contextConfig) {
				logger.debug({ agentId }, "No context config found for agent");
				return null;
			}
			await handleContextConfigChange(executionContext, conversationId, contextConfig.id, credentialStores);
			trigger = await determineContextTrigger(tenantId, projectId, conversationId);
			const contextResult = await new ContextResolver(executionContext, credentialStores).resolve(contextConfig, {
				triggerEvent: trigger,
				conversationId,
				headers: headers$1,
				tenantId
			});
			logger.info({ contextResult }, "Context result");
			const resolvedContext = {
				...contextResult.resolvedContext,
				$env: process.env
			};
			await updateConversation(runDbClient_default)({
				scopes: {
					tenantId,
					projectId
				},
				conversationId,
				data: { lastContextResolution: (/* @__PURE__ */ new Date()).toISOString() }
			});
			if (contextResult.errors.length > 0) parentSpan.setStatus({
				code: SpanStatusCode.ERROR,
				message: `Context resolution completed with errors`
			});
			else parentSpan.setStatus({ code: SpanStatusCode.OK });
			logger.info({
				conversationId,
				agentId,
				contextConfigId: contextConfig.id,
				trigger,
				resolvedKeys: Object.keys(resolvedContext),
				cacheHits: contextResult.cacheHits.length,
				cacheMisses: contextResult.cacheMisses.length,
				fetchedDefinitions: contextResult.fetchedDefinitions.length,
				errors: contextResult.errors.length
			}, "Context resolution completed (contextConfigId derived from agent)");
			return resolvedContext;
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : "Unknown error";
			parentSpan.setAttributes({
				"context.final_status": "failed",
				"context.error_message": errorMessage
			});
			setSpanWithError(parentSpan, error instanceof Error ? error : new Error(String(error)));
			logger.error({
				error: errorMessage,
				contextConfigId: agent?.contextConfig?.id,
				trigger: await determineContextTrigger(tenantId, projectId, conversationId).catch(() => "unknown")
			}, "Failed to resolve context, proceeding without context resolution");
			return null;
		} finally {
			parentSpan.end();
		}
	});
}

//#endregion
export { determineContextTrigger, handleContextConfigChange, handleContextResolution };