import { SENTINEL_KEY } from "../constants/artifact-syntax.js";
import { ToolChainResolutionError } from "../artifacts/ArtifactParser.js";
import { DANGEROUS_PATTERNS } from "@inkeep/agents-core/utils/signature-validation";
import * as jmespath$1 from "jmespath";

//#region src/domains/run/utils/select-filter.ts
function clearSelectorCache() {
	selectorCache.clear();
}
/**
* Strip internal fields (prefixed with _) from a tool result object.
* Removes _structureHints, _toolCallId, etc. that are added for LLM context
* but should not appear in traces, stored results, or downstream data.
*/
function stripInternalFields(data) {
	if (data && typeof data === "object" && !Array.isArray(data)) return Object.fromEntries(Object.entries(data).filter(([key]) => !key.startsWith("_")));
	return data;
}
const selectorCache = /* @__PURE__ */ new Map();
const SELECTOR_CACHE_MAX = 1e3;
const MAX_EXPRESSION_LENGTH = 1e3;
/**
* Sanitize JMESPath selector to fix common LLM syntax issues.
* Extracted from ArtifactService for reuse in _select filtering.
*/
function sanitizeJMESPathSelector(selector) {
	const cached = selectorCache.get(selector);
	if (cached !== void 0) return cached;
	let sanitized = selector.replace(/=="([^"]*)"/g, "=='$1'");
	sanitized = sanitized.replace(/\[\?(\w+)\s*~\s*contains\(@,\s*"([^"]*)"\)\]/g, "[?contains($1, `$2`)]");
	sanitized = sanitized.replace(/\[\?(\w+)\s*~\s*contains\(@,\s*'([^']*)'\)\]/g, "[?contains($1, `$2`)]");
	sanitized = sanitized.replace(/\s*~\s*/g, " ");
	if (selectorCache.size < SELECTOR_CACHE_MAX) selectorCache.set(selector, sanitized);
	return sanitized;
}
function validateSelector(expression, toolCallId, originalSelector) {
	if (expression.length > MAX_EXPRESSION_LENGTH) throw new ToolChainResolutionError(toolCallId, `${SENTINEL_KEY.SELECT} expression exceeds maximum length of ${MAX_EXPRESSION_LENGTH} characters. Expression: ${originalSelector}`);
	for (const pattern of DANGEROUS_PATTERNS) if (pattern.test(expression)) throw new ToolChainResolutionError(toolCallId, `${SENTINEL_KEY.SELECT} expression contains dangerous pattern. Expression: ${originalSelector}`);
}
function summarizeShape(data, maxDepth = 3, currentDepth = 0) {
	if (data === null || data === void 0) return "null";
	if (typeof data === "string") return `string(len=${data.length})`;
	if (typeof data === "number" || typeof data === "boolean") return String(typeof data);
	if (Array.isArray(data)) {
		if (data.length === 0) return "[]";
		if (currentDepth >= maxDepth) return `array(len=${data.length})`;
		return `[${summarizeShape(data[0], maxDepth, currentDepth + 1)}](len=${data.length})`;
	}
	if (typeof data === "object") {
		const keys = Object.keys(data).filter((k) => !k.startsWith("_"));
		if (keys.length === 0) return "{}";
		if (currentDepth >= maxDepth) return `{${keys.slice(0, 10).join(", ")}${keys.length > 10 ? ", ..." : ""}}`;
		return `{${keys.slice(0, 10).map((k) => `${k}: ${summarizeShape(data[k], maxDepth, currentDepth + 1)}`).join(", ")}${keys.length > 10 ? ", ..." : ""}}`;
	}
	return typeof data;
}
/**
* Apply a JMESPath SENTINEL_KEY.SELECT filter to resolved tool/artifact data.
*
* - Auto-strips `result.` prefix (matches _structureHints selector format)
* - Sanitizes common LLM JMESPath errors
* - Validates for security (injection patterns, length)
* - Returns filtered data or null if selector matches nothing
* - Throws ToolChainResolutionError on invalid expressions
*/
function applySelector(data, selector, toolCallId) {
	let expression = selector.trim();
	if (expression.startsWith("result.")) expression = expression.slice(7);
	expression = sanitizeJMESPathSelector(expression);
	validateSelector(expression, toolCallId, selector);
	try {
		const result = jmespath$1.search(data, expression);
		if (result === null || result === void 0) {
			const dataPreview = summarizeShape(data);
			throw new ToolChainResolutionError(toolCallId, `${SENTINEL_KEY.SELECT} matched nothing. The expression "${selector}" did not match any data in the tool result. Available data shape: ${dataPreview}. Check _structureHints and try a different selector.`);
		}
		return result;
	} catch (error) {
		if (error instanceof ToolChainResolutionError) throw error;
		throw new ToolChainResolutionError(toolCallId, `${SENTINEL_KEY.SELECT} filter failed: ${error instanceof Error ? error.message : String(error)}. Expression: ${selector}`);
	}
}

//#endregion
export { applySelector, clearSelectorCache, sanitizeJMESPathSelector, stripInternalFields };