import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { init_paths, resolveConfigPath } from "../../config/paths.js";
import { ConfigSchema, init_schema } from "../../config/schema.js";
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
import { commandRegistry } from "../registry.js";
import { resolveAllowlistMatchSimple } from "../../channels/security.js";
import { parseConfigValue } from "../config-value.js";
import { getConfigValueAtPath, parseConfigPath, setConfigValueAtPath, unsetConfigValueAtPath } from "../config-paths.js";
//#region src/chat-commands/builtins/config.ts
init_schema();
init_loader();
init_paths();
init_logger();
init_session_key();
const log = createLogger("ConfigCommand");
const BLOCKED_WRITE_PATHS = new Set(["gateway.auth.token", "providers"]);
function isBlockedPath(path) {
	const joined = path.join(".");
	for (const blocked of BLOCKED_WRITE_PATHS) if (joined === blocked || joined.startsWith(`${blocked}.`)) return true;
	return false;
}
function redactConfigForDisplay(plain) {
	if (plain.gateway && typeof plain.gateway === "object") {
		const gw = plain.gateway;
		if (gw.auth && typeof gw.auth === "object") gw.auth.token = "[redacted]";
	}
	if (plain.providers !== void 0) plain.providers = "[redacted]";
}
function senderMayWritePersistentConfig(ctx) {
	const { source, senderId, isGroup, sessionKey } = ctx;
	if (source !== "telegram" && source !== "weixin") return true;
	const cfg = ctx.getConfig?.() ?? ctx.config;
	if (source === "weixin") {
		const wx = cfg.channels?.weixin;
		if (!wx?.enabled) return false;
		const accountId = parseSessionKey(sessionKey)?.accountId ?? "default";
		let allowFrom = [];
		if (wx.accounts && Object.keys(wx.accounts).length > 0) {
			const acc = wx.accounts[accountId] ?? wx.accounts["default"];
			if (!acc || acc.enabled === false) return false;
			allowFrom = [...acc.allowFrom ?? []];
		} else allowFrom = [...wx.allowFrom ?? []];
		if (allowFrom.length === 0) return false;
		return resolveAllowlistMatchSimple({
			allowFrom,
			senderId
		}).allowed;
	}
	const tg = cfg.channels?.telegram;
	if (!tg?.enabled) return false;
	const accountId = parseSessionKey(sessionKey)?.accountId ?? "default";
	let allowFrom = [];
	let groupAllowFrom = [];
	if (tg.accounts && Object.keys(tg.accounts).length > 0) {
		const acc = tg.accounts[accountId] ?? tg.accounts["default"];
		if (!acc || acc.enabled === false) return false;
		allowFrom = [...acc.allowFrom ?? []];
		groupAllowFrom = [...acc.groupAllowFrom ?? []];
	} else {
		allowFrom = [...tg.allowFrom ?? []];
		groupAllowFrom = [...tg.groupAllowFrom ?? []];
	}
	const list = isGroup && groupAllowFrom.length > 0 ? groupAllowFrom : allowFrom;
	if (list.length === 0) return false;
	return resolveAllowlistMatchSimple({
		allowFrom: list,
		senderId
	}).allowed;
}
const configCommand = {
	id: "system.config",
	name: "config",
	aliases: ["cfg"],
	description: "Show or update configuration. Usage: /config show [path] | /config set path=value | /config unset path",
	category: "system",
	scope: [
		"global",
		"private",
		"group"
	],
	acceptsArgs: true,
	examples: [
		"/config show",
		"/config show agents.defaults.model",
		"/config set agents.defaults.model=anthropic/claude-opus-4-5",
		"/config set agents.defaults.temperature=0.5",
		"/config unset tts"
	],
	handler: async (ctx, args) => {
		const parts = args.trim().split(/\s+/);
		const action = parts[0]?.toLowerCase();
		const rest = parts.slice(1).join(" ").trim();
		if (!action || action === "show" || action === "get") {
			const config = ctx.getConfig?.() ?? loadConfig(resolveConfigPath());
			const plain = JSON.parse(JSON.stringify(config));
			redactConfigForDisplay(plain);
			if (rest) {
				const parsed = parseConfigPath(rest);
				if (!parsed.ok || !parsed.path) return {
					content: `⚠️ ${parsed.error ?? "Invalid path."}`,
					success: false
				};
				const value = getConfigValueAtPath(plain, parsed.path);
				return { content: `⚙️ \`${rest}\`:\n\`\`\`json\n${JSON.stringify(value ?? null, null, 2)}\n\`\`\`` };
			}
			return { content: `⚙️ Current config:\n\`\`\`json\n${JSON.stringify(plain, null, 2)}\n\`\`\`` };
		}
		if (action === "set") {
			if (!senderMayWritePersistentConfig(ctx)) return {
				content: "⚠️ You are not allowed to change config from this chat surface.",
				success: false
			};
			const eqIndex = rest.indexOf("=");
			if (eqIndex <= 0) return {
				content: "⚠️ Usage: /config set path=value",
				success: false
			};
			const pathRaw = rest.slice(0, eqIndex).trim();
			const valueRaw = rest.slice(eqIndex + 1);
			const parsedPath = parseConfigPath(pathRaw);
			if (!parsedPath.ok || !parsedPath.path) return {
				content: `⚠️ ${parsedPath.error}`,
				success: false
			};
			if (isBlockedPath(parsedPath.path)) return {
				content: `⚠️ Path \`${pathRaw}\` cannot be modified via chat for security reasons.`,
				success: false
			};
			const parsedValue = parseConfigValue(valueRaw);
			if (parsedValue.ok === false) return {
				content: `⚠️ ${parsedValue.error}`,
				success: false
			};
			const currentConfig = loadConfig(resolveConfigPath());
			setConfigValueAtPath(currentConfig, parsedPath.path, parsedValue.value);
			const validated = ConfigSchema.safeParse(currentConfig);
			if (!validated.success) {
				const firstIssue = validated.error.issues[0];
				return {
					content: `⚠️ Config invalid after set (${firstIssue.path.join(".")}: ${firstIssue.message}). Change not saved.`,
					success: false
				};
			}
			await saveConfig(validated.data);
			log.info({
				path: pathRaw,
				value: parsedValue.value
			}, "Config updated via /config set");
			return { content: `⚙️ Config updated: \`${pathRaw}\` = ${typeof parsedValue.value === "string" ? `"${parsedValue.value}"` : JSON.stringify(parsedValue.value)}` };
		}
		if (action === "unset") {
			if (!senderMayWritePersistentConfig(ctx)) return {
				content: "⚠️ You are not allowed to change config from this chat surface.",
				success: false
			};
			if (!rest) return {
				content: "⚠️ Usage: /config unset path",
				success: false
			};
			const parsedPath = parseConfigPath(rest);
			if (!parsedPath.ok || !parsedPath.path) return {
				content: `⚠️ ${parsedPath.error}`,
				success: false
			};
			if (isBlockedPath(parsedPath.path)) return {
				content: `⚠️ Path \`${rest}\` cannot be modified via chat for security reasons.`,
				success: false
			};
			const currentConfig = loadConfig(resolveConfigPath());
			if (!unsetConfigValueAtPath(currentConfig, parsedPath.path)) return {
				content: `⚙️ No config value found at \`${rest}\`.`,
				success: false
			};
			const validated = ConfigSchema.safeParse(currentConfig);
			if (!validated.success) {
				const firstIssue = validated.error.issues[0];
				return {
					content: `⚠️ Config invalid after unset (${firstIssue.path.join(".")}: ${firstIssue.message}). Change not saved.`,
					success: false
				};
			}
			await saveConfig(validated.data);
			log.info({ path: rest }, "Config key removed via /config unset");
			return { content: `⚙️ Config updated: \`${rest}\` removed.` };
		}
		return { content: "⚙️ *Config Command*\n\n`/config show [path]` — view config (or a specific path)\n`/config set path=value` — update a config value\n`/config unset path` — remove a config key\n\nExamples:\n`/config show agents.defaults.model`\n`/config set agents.defaults.temperature=0.5`\n`/config set agents.defaults.thinkingDefault=medium`\n`/config unset tts`" };
	}
};
function registerConfigCommand() {
	commandRegistry.register(configCommand);
}
//#endregion
export { registerConfigCommand };

//# sourceMappingURL=config.js.map