import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { execSync } from "child_process";
//#region src/config/resolve-config-value.ts
/**
* Resolve configuration values that may be shell commands, environment variables, or literals.
* Used by model-registry.ts for apiKey and headers resolution.
*/
/**
* Clean expired cache entries and enforce size limit (LRU eviction)
*/
function maintainCache() {
	const now = Date.now();
	for (const [key, entry] of commandResultCache.entries()) if (now - entry.timestamp > CACHE_TTL_MS) commandResultCache.delete(key);
	if (commandResultCache.size > MAX_CACHE_SIZE) {
		const sortedEntries = [...commandResultCache.entries()].sort((a, b) => a[1].timestamp - b[1].timestamp);
		const entriesToDelete = sortedEntries.slice(0, sortedEntries.length - MAX_CACHE_SIZE);
		for (const [key] of entriesToDelete) commandResultCache.delete(key);
	}
}
/**
* Validate if a command is safe to execute
*/
function isSafeCommand(command) {
	for (const pattern of DANGEROUS_PATTERNS) if (pattern.test(command)) return {
		safe: false,
		error: "Command contains potentially dangerous characters"
	};
	const baseCommand = command.trim().split(/\s+/)[0];
	if (!ALLOWED_COMMANDS.includes(baseCommand)) return {
		safe: false,
		error: `Command "${baseCommand}" is not in the allowed list. Allowed: ${ALLOWED_COMMANDS.join(", ")}`
	};
	return { safe: true };
}
/**
* Resolve a config value (API key, header value, etc.) to an actual value.
* - If starts with "!", executes the rest as a shell command and uses stdout (cached)
* - If matches an environment variable name (all uppercase with underscores), uses env value
* - Otherwise treats as literal value
*/
function resolveConfigValue(config) {
	if (config.startsWith("!")) return executeCommand(config);
	if (/^[A-Z][A-Z0-9_]*$/.test(config)) {
		const envValue = process.env[config];
		if (envValue !== void 0) return envValue;
	}
	return config;
}
function executeCommand(commandConfig) {
	maintainCache();
	const cached = commandResultCache.get(commandConfig);
	if (cached) {
		if (Date.now() - cached.timestamp <= CACHE_TTL_MS) return cached.value;
	}
	const command = commandConfig.slice(1);
	const safety = isSafeCommand(command);
	if (!safety.safe) {
		console.error(`[Security] Blocked unsafe command: ${safety.error}`);
		return;
	}
	let result;
	try {
		result = execSync(command, {
			encoding: "utf-8",
			timeout: 1e4,
			stdio: [
				"ignore",
				"pipe",
				"ignore"
			]
		}).trim() || void 0;
	} catch (err) {
		console.error(`[Config] Command execution failed: ${err instanceof Error ? err.message : "Unknown error"}`);
		result = void 0;
	}
	commandResultCache.set(commandConfig, {
		value: result,
		timestamp: Date.now()
	});
	return result;
}
/**
* Resolve all header values using the same resolution logic as API keys.
*/
function resolveHeaders(headers) {
	if (!headers) return void 0;
	const resolved = {};
	for (const [key, value] of Object.entries(headers)) {
		const resolvedValue = resolveConfigValue(value);
		if (resolvedValue) resolved[key] = resolvedValue;
	}
	return Object.keys(resolved).length > 0 ? resolved : void 0;
}
/** Clear the config value command cache. Exported for testing. */
function clearConfigValueCache() {
	commandResultCache.clear();
}
/** Get cache statistics for monitoring */
function getCacheStats() {
	return {
		size: commandResultCache.size,
		maxSize: MAX_CACHE_SIZE,
		ttlMs: CACHE_TTL_MS
	};
}
/**
* Test API key resolution without caching (for UI testing)
* SECURITY: This function validates commands against a whitelist
*/
function testApiKeyResolution(value) {
	if (value.startsWith("!")) {
		const command = value.slice(1);
		const safety = isSafeCommand(command);
		if (!safety.safe) return {
			type: "command",
			error: `Security: ${safety.error}`
		};
		try {
			return {
				type: "command",
				resolved: execSync(command, {
					encoding: "utf-8",
					timeout: 1e4,
					stdio: [
						"ignore",
						"pipe",
						"ignore"
					]
				}).trim() || void 0
			};
		} catch (err) {
			return {
				type: "command",
				error: err instanceof Error ? err.message : "Command failed"
			};
		}
	}
	if (/^[A-Z][A-Z0-9_]*$/.test(value)) {
		const envValue = process.env[value];
		if (envValue !== void 0) return {
			type: "env",
			resolved: envValue
		};
		return {
			type: "env",
			error: `Environment variable ${value} is not set`
		};
	}
	return {
		type: "literal",
		resolved: value
	};
}
/**
* Get the list of allowed commands (for documentation/UI)
*/
function getAllowedCommands() {
	return [...ALLOWED_COMMANDS];
}
var MAX_CACHE_SIZE, CACHE_TTL_MS, commandResultCache, ALLOWED_COMMANDS, DANGEROUS_PATTERNS;
var init_resolve_config_value = __esmMin((() => {
	MAX_CACHE_SIZE = 100;
	CACHE_TTL_MS = 300 * 1e3;
	commandResultCache = /* @__PURE__ */ new Map();
	ALLOWED_COMMANDS = [
		"op",
		"security",
		"pass",
		"gpg"
	];
	DANGEROUS_PATTERNS = [
		/[;&|]/,
		/>/,
		/</,
		/\$\(/,
		/`/,
		/\$\{.*\}/,
		/\*\*?/,
		/\.\./
	];
}));
//#endregion
init_resolve_config_value();
export { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution };

//# sourceMappingURL=resolve-config-value.js.map