import { a as normalizeLowercaseStringOrEmpty, c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js";
import { l as normalizeStringEntries } from "./string-normalization-WNUDCpXX.js";
import { a as normalizeAnyChannelId } from "./registry-C-oZjd7N.js";
import { t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-constants-Z0pS5ykd.js";
import { r as listLoadedChannelPlugins, t as getLoadedChannelPluginById } from "./registry-loaded-7dE83LUI.js";
import { i as normalizeMessageChannel } from "./message-channel-normalize-C9fk76RO.js";
import { r as isInternalMessageChannel } from "./message-channel-ClBB0edl.js";
import { a as isNativeCommandTurn, s as resolveCommandTurnContext } from "./command-turn-context-YXLLZVCi.js";
//#region src/auto-reply/sender-identity.ts
/** Shared sender identity helpers for authorization checks. */
function isConversationLikeIdentity(value) {
	const normalized = normalizeOptionalLowercaseString(value);
	if (!normalized) return false;
	if (normalized.startsWith("chat_id:")) return true;
	return /(^|:)(channel|group|thread|topic|room|space|spaces):/.test(normalized);
}
function shouldUseFromAsSenderFallback(params) {
	const from = normalizeOptionalString(params.from) ?? "";
	if (!from) return false;
	const chatType = normalizeLowercaseStringOrEmpty(params.chatType);
	if (chatType && chatType !== "direct") return false;
	return !isConversationLikeIdentity(from);
}
//#endregion
//#region src/auto-reply/command-auth.ts
/** Command authorization helpers for owner and allowlist checks. */
function resolveProviderFromContext(ctx, cfg) {
	const explicitMessageChannels = [
		ctx.Surface,
		ctx.OriginatingChannel,
		ctx.Provider
	].map((value) => normalizeMessageChannel(value)).filter((value) => Boolean(value));
	const explicitMessageChannel = explicitMessageChannels.find((value) => value !== INTERNAL_MESSAGE_CHANNEL);
	if (!explicitMessageChannel && explicitMessageChannels.includes("webchat")) return {
		providerId: void 0,
		hadResolutionError: false
	};
	const direct = normalizeAnyChannelId(explicitMessageChannel ?? void 0) ?? explicitMessageChannel ?? normalizeAnyChannelId(ctx.Provider) ?? normalizeAnyChannelId(ctx.Surface) ?? normalizeAnyChannelId(ctx.OriginatingChannel);
	if (direct) return {
		providerId: direct,
		hadResolutionError: false
	};
	const candidates = [ctx.From, ctx.To].filter((value) => Boolean(value?.trim())).flatMap((value) => value.split(":").map((part) => part.trim()));
	for (const candidate of candidates) {
		const normalizedCandidateChannel = normalizeMessageChannel(candidate);
		if (normalizedCandidateChannel === "webchat") return {
			providerId: void 0,
			hadResolutionError: false
		};
		const normalized = normalizeAnyChannelId(normalizedCandidateChannel ?? void 0) ?? normalizedCandidateChannel ?? normalizeAnyChannelId(candidate);
		if (normalized) return {
			providerId: normalized,
			hadResolutionError: false
		};
	}
	const inferredProviders = probeInferredProviders(ctx, cfg);
	const inferred = inferredProviders.candidates;
	if (inferred.length === 1) return {
		providerId: inferred[0].providerId,
		hadResolutionError: inferred[0].hadResolutionError
	};
	return {
		providerId: void 0,
		hadResolutionError: inferredProviders.droppedResolutionError || inferred.some((entry) => entry.hadResolutionError)
	};
}
function probeInferredProviders(ctx, cfg) {
	let droppedResolutionError = false;
	return {
		candidates: listLoadedChannelPlugins().map((plugin) => {
			const resolvedAllowFrom = buildProviderAllowFromResolution({
				plugin,
				cfg,
				accountId: ctx.AccountId
			});
			if (resolvedAllowFrom.allowFromList.length === 0) {
				if (resolvedAllowFrom.hadResolutionError) droppedResolutionError = true;
				return null;
			}
			return {
				providerId: plugin.id,
				hadResolutionError: resolvedAllowFrom.hadResolutionError
			};
		}).filter((value) => Boolean(value)),
		droppedResolutionError
	};
}
function formatAllowFromList(params) {
	const { plugin, cfg, accountId, allowFrom } = params;
	if (!allowFrom || allowFrom.length === 0) return [];
	if (plugin?.config?.formatAllowFrom) return plugin.config.formatAllowFrom({
		cfg,
		accountId,
		allowFrom
	});
	return normalizeStringEntries(allowFrom);
}
function normalizeAllowFromEntry(params) {
	return formatAllowFromList({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		allowFrom: [params.value]
	}).filter((entry) => entry.trim().length > 0);
}
function isWildcardAllowFromEntry(entry) {
	return entry.trim() === "*";
}
function hasWildcardAllowFrom(list) {
	return list.some((entry) => isWildcardAllowFromEntry(entry));
}
function stripWildcardAllowFrom(list) {
	return list.filter((entry) => !isWildcardAllowFromEntry(entry));
}
function resolveProviderAllowFrom(params) {
	const { plugin, cfg, accountId } = params;
	const providerId = plugin?.id;
	if (!plugin?.config?.resolveAllowFrom) return {
		allowFrom: resolveFallbackAllowFrom({
			cfg,
			providerId,
			accountId
		}),
		hadResolutionError: false
	};
	try {
		const allowFrom = plugin.config.resolveAllowFrom({
			cfg,
			accountId
		});
		if (allowFrom == null) return {
			allowFrom: [],
			hadResolutionError: false
		};
		if (!Array.isArray(allowFrom)) {
			console.warn(`[command-auth] resolveAllowFrom returned an invalid allowFrom for provider "${providerId}", falling back to config allowFrom: invalid_result`);
			return {
				allowFrom: resolveFallbackAllowFrom({
					cfg,
					providerId,
					accountId
				}),
				hadResolutionError: true
			};
		}
		return {
			allowFrom,
			hadResolutionError: false
		};
	} catch (err) {
		console.warn(`[command-auth] resolveAllowFrom threw for provider "${providerId}", falling back to config allowFrom: ${describeAllowFromResolutionError(err)}`);
		return {
			allowFrom: resolveFallbackAllowFrom({
				cfg,
				providerId,
				accountId
			}),
			hadResolutionError: true
		};
	}
}
function buildProviderAllowFromResolution(params) {
	const providerId = params.providerId ?? params.plugin?.id;
	const resolvedAllowFrom = params.forceFallbackResolutionError ? {
		allowFrom: resolveFallbackAllowFrom({
			cfg: params.cfg,
			providerId,
			accountId: params.accountId
		}),
		hadResolutionError: true
	} : resolveProviderAllowFrom({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId
	});
	return {
		...resolvedAllowFrom,
		allowFromList: formatAllowFromList({
			plugin: params.plugin,
			cfg: params.cfg,
			accountId: params.accountId,
			allowFrom: resolvedAllowFrom.allowFrom
		})
	};
}
function describeAllowFromResolutionError(err) {
	if (err instanceof Error) return (normalizeOptionalString(err.name) ?? "") || "Error";
	return "unknown_error";
}
function resolveOwnerAllowFromList(params) {
	const raw = params.allowFrom ?? params.cfg.commands?.ownerAllowFrom;
	if (!Array.isArray(raw) || raw.length === 0) return [];
	const filtered = [];
	for (const entry of raw) {
		const trimmed = normalizeOptionalString(String(entry ?? "")) ?? "";
		if (!trimmed) continue;
		const separatorIndex = trimmed.indexOf(":");
		if (separatorIndex > 0) {
			const channel = normalizeAnyChannelId(trimmed.slice(0, separatorIndex));
			if (channel) {
				if (!params.providerId || channel !== params.providerId) continue;
				const remainder = trimmed.slice(separatorIndex + 1).trim();
				if (remainder) filtered.push(remainder);
				continue;
			}
		}
		filtered.push(trimmed);
	}
	return formatAllowFromList({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		allowFrom: filtered
	});
}
/**
* Resolves the commands.allowFrom list for a given provider.
* Returns the provider-specific list if defined, otherwise the "*" global list.
* Returns null if commands.allowFrom is not configured at all (fall back to channel allowFrom).
*/
function resolveCommandsAllowFromList(params) {
	const { plugin, cfg, accountId, providerId } = params;
	const commandsAllowFrom = cfg.commands?.allowFrom;
	if (!commandsAllowFrom || typeof commandsAllowFrom !== "object") return null;
	const providerList = commandsAllowFrom[providerId ?? ""];
	const globalList = commandsAllowFrom["*"];
	const rawList = Array.isArray(providerList) ? providerList : globalList;
	if (!Array.isArray(rawList)) return null;
	return formatAllowFromList({
		plugin,
		cfg,
		accountId,
		allowFrom: rawList
	});
}
function resolveOwnerCandidatesForCommands(params) {
	if (params.allowAll) return [];
	const ownerCandidatesForCommands = stripWildcardAllowFrom(params.allowFromList);
	if (ownerCandidatesForCommands.length > 0 || !params.to) return ownerCandidatesForCommands;
	const normalizedTo = normalizeAllowFromEntry({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		value: params.to
	});
	return normalizedTo.length > 0 ? [...ownerCandidatesForCommands, ...normalizedTo] : [];
}
function resolveOwnerAuthorizationState(params) {
	const configOwnerAllowFromList = resolveOwnerAllowFromList({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		providerId: params.providerId,
		allowFrom: params.configOwnerAllowFrom
	});
	const contextOwnerAllowFromList = resolveOwnerAllowFromList({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		providerId: params.providerId,
		allowFrom: params.contextOwnerAllowFrom
	});
	const allowAll = !params.hadResolutionError && (params.allowFromList.length === 0 || hasWildcardAllowFrom(params.allowFromList));
	const ownerCandidatesForCommands = resolveOwnerCandidatesForCommands({
		plugin: params.plugin,
		cfg: params.cfg,
		accountId: params.accountId,
		to: params.to,
		allowAll,
		allowFromList: params.allowFromList
	});
	const ownerAllowAll = hasWildcardAllowFrom(configOwnerAllowFromList);
	const explicitOwners = stripWildcardAllowFrom(configOwnerAllowFromList);
	const explicitOverrides = stripWildcardAllowFrom(contextOwnerAllowFromList);
	return {
		allowAll,
		ownerAllowAll,
		ownerCandidatesForCommands,
		explicitOwners,
		ownerList: Array.from(new Set(explicitOwners.length > 0 ? explicitOwners : ownerAllowAll ? [] : explicitOverrides.length > 0 ? explicitOverrides : ownerCandidatesForCommands))
	};
}
function resolveCommandSenderAuthorization(params) {
	if (params.enforceOwnerForCommands && !params.isOwnerForCommands) return false;
	if (params.commandsAllowFromList !== null || params.providerResolutionError && params.commandsAllowFromConfigured) {
		const commandsAllowFromList = params.commandsAllowFromList;
		const commandsAllowAll = !params.providerResolutionError && Boolean(commandsAllowFromList && hasWildcardAllowFrom(commandsAllowFromList));
		const matchedCommandsAllowFrom = commandsAllowFromList?.length ? params.senderCandidates.find((candidate) => commandsAllowFromList.includes(candidate)) : void 0;
		return !params.providerResolutionError && (commandsAllowAll || Boolean(matchedCommandsAllowFrom));
	}
	return params.commandAuthorized && (params.isOwnerForCommands || params.nativeCommandAuthorized);
}
function resolveSenderCandidates(params) {
	const { plugin, cfg, accountId } = params;
	const candidates = [];
	const pushCandidate = (value) => {
		const trimmed = normalizeOptionalString(value) ?? "";
		if (!trimmed) return;
		candidates.push(trimmed);
	};
	if (plugin?.commands?.preferSenderE164ForCommands) {
		pushCandidate(params.senderE164);
		pushCandidate(params.senderId);
	} else {
		pushCandidate(params.senderId);
		pushCandidate(params.senderE164);
	}
	if (candidates.length === 0 && shouldUseFromAsSenderFallback({
		from: params.from,
		chatType: params.chatType
	})) pushCandidate(params.from);
	const normalized = [];
	for (const sender of candidates) {
		const entries = normalizeAllowFromEntry({
			plugin,
			cfg,
			accountId,
			value: sender
		});
		for (const entry of entries) if (!normalized.includes(entry)) normalized.push(entry);
	}
	return normalized;
}
function resolveFallbackAllowFrom(params) {
	const providerId = normalizeOptionalString(params.providerId);
	if (!providerId) return [];
	const channelCfg = params.cfg.channels?.[providerId];
	const accountCfg = resolveFallbackAccountConfig(channelCfg?.accounts, params.accountId) ?? resolveFallbackDefaultAccountConfig(channelCfg);
	const allowFrom = accountCfg?.allowFrom ?? accountCfg?.dm?.allowFrom ?? channelCfg?.allowFrom ?? channelCfg?.dm?.allowFrom;
	return Array.isArray(allowFrom) ? allowFrom : [];
}
function resolveFallbackAccountConfig(accounts, accountId) {
	const normalizedAccountId = normalizeOptionalLowercaseString(accountId);
	if (!accounts || !normalizedAccountId) return;
	const direct = accounts[normalizedAccountId];
	if (direct) return direct;
	const matchKey = Object.keys(accounts).find((key) => normalizeOptionalLowercaseString(key) === normalizedAccountId);
	return matchKey ? accounts[matchKey] : void 0;
}
function resolveFallbackDefaultAccountConfig(channelCfg) {
	const accounts = channelCfg?.accounts;
	if (!accounts) return;
	const preferred = resolveFallbackAccountConfig(accounts, channelCfg?.defaultAccount) ?? resolveFallbackAccountConfig(accounts, "default");
	if (preferred) return preferred;
	const definedAccounts = Object.values(accounts).filter(Boolean);
	return definedAccounts.length === 1 ? definedAccounts[0] : void 0;
}
function resolveCommandAuthorization(params) {
	const { ctx, cfg, commandAuthorized } = params;
	const { providerId, hadResolutionError: providerResolutionError } = resolveProviderFromContext(ctx, cfg);
	const plugin = providerId ? getLoadedChannelPluginById(providerId) ?? void 0 : void 0;
	const from = normalizeOptionalString(ctx.From) ?? "";
	const to = normalizeOptionalString(ctx.To) ?? "";
	const commandsAllowFromConfigured = Boolean(cfg.commands?.allowFrom && typeof cfg.commands.allowFrom === "object");
	const commandsAllowFromList = resolveCommandsAllowFromList({
		plugin,
		cfg,
		accountId: ctx.AccountId,
		providerId
	});
	const resolvedAllowFrom = buildProviderAllowFromResolution({
		plugin,
		cfg,
		accountId: ctx.AccountId,
		providerId,
		forceFallbackResolutionError: providerResolutionError
	});
	const ownerState = resolveOwnerAuthorizationState({
		plugin,
		cfg,
		accountId: ctx.AccountId,
		providerId,
		to,
		allowFromList: resolvedAllowFrom.allowFromList,
		hadResolutionError: resolvedAllowFrom.hadResolutionError,
		configOwnerAllowFrom: cfg.commands?.ownerAllowFrom,
		contextOwnerAllowFrom: ctx.OwnerAllowFrom
	});
	const senderCandidates = resolveSenderCandidates({
		plugin,
		providerId,
		cfg,
		accountId: ctx.AccountId,
		senderId: ctx.SenderId,
		senderE164: ctx.SenderE164,
		from,
		chatType: ctx.ChatType
	});
	const matchedSender = ownerState.ownerList.length ? senderCandidates.find((candidate) => ownerState.ownerList.includes(candidate)) : void 0;
	const matchedCommandOwner = ownerState.ownerCandidatesForCommands.length ? senderCandidates.find((candidate) => ownerState.ownerCandidatesForCommands.includes(candidate)) : void 0;
	const senderId = matchedSender ?? senderCandidates[0];
	const enforceOwner = Boolean(plugin?.commands?.enforceOwnerForCommands);
	const senderIsOwnerByIdentity = Boolean(matchedSender);
	const senderIsOwnerByScope = isInternalMessageChannel(ctx.Provider) && Array.isArray(ctx.GatewayClientScopes) && ctx.GatewayClientScopes.includes("operator.admin");
	const ownerAllowlistConfigured = ownerState.ownerAllowAll || ownerState.explicitOwners.length > 0;
	const senderIsOwner = senderIsOwnerByIdentity || senderIsOwnerByScope || ownerState.ownerAllowAll;
	const requireOwner = enforceOwner || ownerAllowlistConfigured;
	const isOwnerForCommands = !requireOwner ? true : ownerState.ownerAllowAll ? true : ownerAllowlistConfigured ? senderIsOwner : senderIsOwnerByScope || Boolean(matchedCommandOwner);
	const isAuthorizedSender = resolveCommandSenderAuthorization({
		commandAuthorized,
		enforceOwnerForCommands: enforceOwner,
		nativeCommandAuthorized: commandAuthorized && isNativeCommandTurn(resolveCommandTurnContext(ctx)) && !requireOwner,
		isOwnerForCommands,
		senderCandidates,
		commandsAllowFromList,
		providerResolutionError,
		commandsAllowFromConfigured
	});
	return {
		providerId,
		ownerList: ownerState.ownerList,
		senderId: senderId || void 0,
		senderIsOwner,
		isAuthorizedSender,
		from: from || void 0,
		to: to || void 0
	};
}
//#endregion
export { shouldUseFromAsSenderFallback as n, resolveCommandAuthorization as t };
