import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { getSpeechProvider, listSpeechProviders } from "./speech-registry.js";
import "./providers/index.js";
import { buildTtsResolveRawConfig } from "./config-slice.js";
//#region src/voice/tts/factory.ts
init_logger();
const log = createLogger("TTS:Factory");
/** Resolve a single provider id → plugin + per-call config, or null if unavailable. */
function resolveSpeechProvider(providerId, config) {
	const plugin = getSpeechProvider(providerId);
	if (!plugin) {
		log.warn({ providerId }, `Unknown TTS provider "${providerId}" (not registered)`);
		return null;
	}
	const rawConfig = buildTtsResolveRawConfig(providerId, config);
	const timeoutMs = config.timeoutMs ?? 3e4;
	const providerConfig = plugin.resolveConfig({
		cfg: void 0,
		rawConfig,
		timeoutMs
	});
	if (!plugin.isConfigured({
		providerConfig,
		timeoutMs
	})) {
		log.debug({ providerId }, `Provider "${providerId}" reports not configured; skipping`);
		return null;
	}
	return {
		plugin,
		providerId,
		providerConfig,
		timeoutMs
	};
}
/** Order providers: explicit fallback when enabled, otherwise auto-select by registry order. */
function resolveProviderOrder(primary, fallback, config) {
	if (fallback?.enabled && fallback.order.length > 0) {
		const order = [primary];
		for (const provider of fallback.order) if (provider !== primary && !order.includes(provider)) order.push(provider);
		return order;
	}
	const configured = listSpeechProviders().map((plugin) => {
		return resolveSpeechProvider(plugin.id, config) ? plugin : null;
	}).filter((plugin) => plugin !== null).sort((left, right) => {
		const leftOrder = left.autoSelectOrder ?? Number.MAX_SAFE_INTEGER;
		const rightOrder = right.autoSelectOrder ?? Number.MAX_SAFE_INTEGER;
		if (leftOrder !== rightOrder) return leftOrder - rightOrder;
		return left.id.localeCompare(right.id);
	}).map((plugin) => plugin.id);
	const order = [primary];
	for (const providerId of configured) if (providerId !== primary && !order.includes(providerId)) order.push(providerId);
	return order;
}
/** Resolve the full provider chain in priority order; only configured plugins included. */
function resolveSpeechProviderChain(config) {
	if (!config.enabled) throw new Error("TTS is not enabled");
	const order = resolveProviderOrder(config.provider, config.fallback, config);
	const chain = [];
	for (const providerId of order) {
		const resolved = resolveSpeechProvider(providerId, config);
		if (resolved) chain.push(resolved);
	}
	if (chain.length === 0) throw new Error("No TTS providers are available");
	log.debug({
		primary: config.provider,
		chain: chain.map((c) => c.providerId)
	}, "TTS provider chain resolved");
	return chain;
}
function isTTSAvailable(config) {
	if (!config?.enabled) return false;
	try {
		return resolveSpeechProviderChain(config).length > 0;
	} catch {
		return false;
	}
}
function isProviderConfigured(provider, config) {
	return resolveSpeechProvider(provider, config) !== null;
}
function getAvailableProviders(config) {
	return listSpeechProviders().map((plugin) => plugin.id).filter((provider) => isProviderConfigured(provider, config));
}
/** List all registered SpeechProviderPlugin ids — primarily for the gateway console. */
function listRegisteredSpeechProviderIds() {
	return listSpeechProviders().map((plugin) => plugin.id);
}
//#endregion
export { getAvailableProviders, isProviderConfigured, isTTSAvailable, listRegisteredSpeechProviderIds, resolveProviderOrder, resolveSpeechProvider, resolveSpeechProviderChain };

//# sourceMappingURL=factory.js.map