import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
import { init_account_id, normalizeAccountId } from "./account-id.js";
import { buildAgentMainSessionKey, buildAgentPeerSessionKey, init_agent_session_key, normalizeSessionKey } from "./agent-session-key.js";
import { buildSessionKey, init_session_key, parseSessionKey } from "./session-key.js";
import { init_bindings, parseBindingRules, resolveRoute as resolveRoute$1 } from "./bindings.js";
//#region src/routing/resolve-route.ts
/**
* Apply identity links and return a canonical lowercased peer id.
*/
function applyIdentityLinks(peerId, channel, identityLinks) {
	if (!identityLinks) return peerId.toLowerCase();
	const normalizedPeerId = peerId.trim().toLowerCase();
	if (!normalizedPeerId) return normalizedPeerId;
	const candidates = /* @__PURE__ */ new Set();
	candidates.add(normalizedPeerId);
	const channelPrefix = channel.trim().toLowerCase();
	if (channelPrefix) candidates.add(`${channelPrefix}:${normalizedPeerId}`);
	for (const [canonical, aliases] of Object.entries(identityLinks)) {
		if (!Array.isArray(aliases)) continue;
		for (const alias of aliases) {
			const normalizedAlias = alias.trim().toLowerCase();
			if (candidates.has(normalizedAlias)) return canonical.trim().toLowerCase();
		}
	}
	return normalizedPeerId;
}
/**
* Default agent id from config (`agents.default`, `list[].default`, or `main`).
*/
function getDefaultAgentId(config) {
	return resolveDefaultAgentId(config);
}
/**
* Whether `agentId` appears in the enabled agent list (or list is absent).
*/
function agentExists(agentId, config) {
	if (!config.agents?.list) return true;
	return config.agents.list.some((agent) => agent.enabled !== false && agent.id.toLowerCase() === agentId.toLowerCase());
}
/**
* Return `agentId` if listed, otherwise the default agent id.
*/
function pickFirstExistingAgentId(agentId, config) {
	if (!agentId) return getDefaultAgentId(config);
	if (agentExists(agentId, config)) return agentId.toLowerCase();
	return getDefaultAgentId(config);
}
/**
* Thin wrapper around `buildSessionKey` for route inputs.
*/
function buildRouteSessionKey(agentId, channel, accountId, peerKind, peerId, threadId, scopeId) {
	return buildSessionKey({
		agentId,
		source: channel,
		accountId,
		peerKind,
		peerId,
		threadId: threadId || void 0,
		scopeId: scopeId || void 0,
		dmScope: peerKind === "dm" || peerKind === "direct" ? "per-account-channel-peer" : void 0
	});
}
/**
* Map session vs main key to policy label.
*/
function deriveLastRoutePolicy(sessionKey, mainSessionKey) {
	return sessionKey === mainSessionKey ? "main" : "session";
}
/**
* Resolve agent and session keys from channel context and config.
*/
function resolveRoute(input) {
	const { config, threadId } = input;
	const channel = (input.channel ?? "").trim().toLowerCase() || "unknown";
	const accountId = normalizeAccountId(input.accountId);
	const peerKind = (input.peerKind ?? "dm").toLowerCase();
	const rawPeerId = (input.peerId ?? "").trim();
	const peerId = applyIdentityLinks(rawPeerId, channel, config.session?.identityLinks ?? {});
	const rules = Array.isArray(config.bindings) ? parseBindingRules({ bindings: config.bindings }) : [];
	const bindingResult = resolveRoute$1({
		channel,
		accountId,
		peerKind: input.peerKind,
		peerId: rawPeerId,
		guildId: input.guildId,
		teamId: input.teamId,
		memberRoleIds: input.memberRoleIds
	}, rules, getDefaultAgentId(config));
	const agentId = pickFirstExistingAgentId(bindingResult.agentId, config);
	const dmScope = config.session?.dmScope ?? "main";
	let sessionKey;
	let mainSessionKey;
	const identityLinks = config.session?.identityLinks;
	const mainKey = void 0;
	if (peerKind === "dm" || peerKind === "direct") {
		mainSessionKey = buildAgentMainSessionKey({
			agentId,
			mainKey
		});
		sessionKey = buildAgentPeerSessionKey({
			agentId,
			mainKey,
			channel,
			accountId,
			peerKind: "direct",
			peerId,
			identityLinks,
			dmScope
		});
	} else {
		const mappedKind = peerKind === "group" || peerKind === "channel" ? peerKind : peerKind;
		sessionKey = buildAgentPeerSessionKey({
			agentId,
			mainKey,
			channel,
			accountId,
			peerKind: mappedKind,
			peerId,
			identityLinks
		});
		mainSessionKey = buildAgentPeerSessionKey({
			agentId,
			mainKey,
			channel,
			accountId,
			peerKind: mappedKind,
			peerId: "main",
			identityLinks
		});
	}
	if (threadId && !sessionKey.includes(":thread:")) sessionKey = `${sessionKey}:thread:${threadId.toLowerCase()}`;
	sessionKey = normalizeSessionKey(sessionKey);
	mainSessionKey = normalizeSessionKey(mainSessionKey);
	return {
		...bindingResult,
		agentId,
		sessionKey,
		mainSessionKey,
		lastRoutePolicy: deriveLastRoutePolicy(sessionKey, mainSessionKey)
	};
}
/**
* Parse basic routing fields from a session key string.
*/
function resolveRouteFromSessionKey(sessionKey, _config) {
	const parsed = parseSessionKey(sessionKey);
	if (!parsed) return null;
	return {
		agentId: parsed.agentId,
		source: parsed.source,
		accountId: parsed.accountId,
		peerKind: parsed.peerKind,
		peerId: parsed.peerId
	};
}
var init_resolve_route = __esmMin((() => {
	init_agent_scope();
	init_bindings();
	init_session_key();
	init_agent_session_key();
	init_account_id();
}));
//#endregion
init_resolve_route();
export { agentExists, applyIdentityLinks, buildRouteSessionKey, deriveLastRoutePolicy, getDefaultAgentId, init_resolve_route, pickFirstExistingAgentId, resolveRoute, resolveRouteFromSessionKey };

//# sourceMappingURL=resolve-route.js.map