import path from "node:path";
import { z } from "zod";
import { loadPersistedConfig } from "./persisted-config.js";
import { ProviderOverrideSchema } from "./agent/provider-launch-config.js";
import { AgentProviderSchema } from "./agent/provider-manifest.js";
import { resolveSpeechConfig } from "./speech/speech-config-resolver.js";
import { mergeHostnames, parseHostnamesEnv } from "./hostnames.js";
const DEFAULT_PORT = 6767;
const DEFAULT_RELAY_ENDPOINT = "relay.paseo.sh:443";
const DEFAULT_APP_BASE_URL = "https://app.paseo.sh";
function parseBooleanEnv(value) {
    if (value === undefined) {
        return undefined;
    }
    const normalized = value.trim().toLowerCase();
    if (["1", "true", "yes", "on"].includes(normalized)) {
        return true;
    }
    if (["0", "false", "no", "off"].includes(normalized)) {
        return false;
    }
    return undefined;
}
const OptionalVoiceLlmProviderSchema = z
    .union([z.string(), z.null(), z.undefined()])
    .transform((value) => typeof value === "string" ? value.trim().toLowerCase() : null)
    .pipe(z.union([AgentProviderSchema, z.null()]));
function parseOptionalVoiceLlmProvider(value) {
    const parsed = OptionalVoiceLlmProviderSchema.safeParse(value);
    return parsed.success ? parsed.data : null;
}
function extractProviderOverrides(providers) {
    if (!providers) {
        return undefined;
    }
    const providerOverrides = Object.entries(providers).flatMap(([providerId, provider]) => {
        const parsed = ProviderOverrideSchema.safeParse(provider);
        return parsed.success ? [[providerId, parsed.data]] : [];
    });
    return providerOverrides.length > 0 ? Object.fromEntries(providerOverrides) : undefined;
}
function extractAgentProviderSettings(providerOverrides) {
    if (!providerOverrides) {
        return undefined;
    }
    const runtimeSettings = Object.entries(providerOverrides).flatMap(([providerId, provider]) => {
        const parsedProviderId = AgentProviderSchema.safeParse(providerId);
        if (!parsedProviderId.success || (!provider.command && !provider.env)) {
            return [];
        }
        return [
            [
                parsedProviderId.data,
                {
                    command: provider.command
                        ? {
                            mode: "replace",
                            argv: provider.command,
                        }
                        : undefined,
                    env: provider.env,
                },
            ],
        ];
    });
    return runtimeSettings.length > 0
        ? Object.fromEntries(runtimeSettings)
        : undefined;
}
export function loadConfig(paseoHome, options) {
    const env = options?.env ?? process.env;
    const persisted = loadPersistedConfig(paseoHome);
    // PASEO_LISTEN can be:
    // - host:port (TCP)
    // - /path/to/socket (Unix socket)
    // - unix:///path/to/socket (Unix socket)
    // Default is TCP at 127.0.0.1:6767
    const listen = options?.cli?.listen ??
        env.PASEO_LISTEN ??
        persisted.daemon?.listen ??
        `127.0.0.1:${env.PORT ?? DEFAULT_PORT}`;
    const envCorsOrigins = env.PASEO_CORS_ORIGINS
        ? env.PASEO_CORS_ORIGINS.split(",").map((s) => s.trim())
        : [];
    const persistedCorsOrigins = persisted.daemon?.cors?.allowedOrigins ?? [];
    const hostnames = mergeHostnames([
        persisted.daemon?.hostnames,
        parseHostnamesEnv(env.PASEO_HOSTNAMES ?? env.PASEO_ALLOWED_HOSTS),
        options?.cli?.hostnames,
    ]);
    const mcpEnabled = options?.cli?.mcpEnabled ?? persisted.daemon?.mcp?.enabled ?? true;
    const mcpInjectIntoAgents = options?.cli?.mcpInjectIntoAgents ?? persisted.daemon?.mcp?.injectIntoAgents ?? false;
    const relayEnabled = options?.cli?.relayEnabled ??
        parseBooleanEnv(env.PASEO_RELAY_ENABLED) ??
        persisted.daemon?.relay?.enabled ??
        true;
    const relayEndpoint = env.PASEO_RELAY_ENDPOINT ?? persisted.daemon?.relay?.endpoint ?? DEFAULT_RELAY_ENDPOINT;
    const relayPublicEndpoint = env.PASEO_RELAY_PUBLIC_ENDPOINT ?? persisted.daemon?.relay?.publicEndpoint ?? relayEndpoint;
    const appBaseUrl = env.PASEO_APP_BASE_URL ?? persisted.app?.baseUrl ?? DEFAULT_APP_BASE_URL;
    const { openai, speech } = resolveSpeechConfig({
        paseoHome,
        env,
        persisted,
    });
    const envVoiceLlmProvider = parseOptionalVoiceLlmProvider(env.PASEO_VOICE_LLM_PROVIDER);
    const persistedVoiceLlmProvider = parseOptionalVoiceLlmProvider(persisted.features?.voiceMode?.llm?.provider);
    const voiceLlmProvider = envVoiceLlmProvider ?? persistedVoiceLlmProvider ?? null;
    const voiceLlmProviderExplicit = envVoiceLlmProvider !== null || persistedVoiceLlmProvider !== null;
    const voiceLlmModel = persisted.features?.voiceMode?.llm?.model ?? null;
    const providerOverrides = extractProviderOverrides(persisted.agents?.providers);
    return {
        listen,
        paseoHome,
        corsAllowedOrigins: Array.from(new Set([...persistedCorsOrigins, ...envCorsOrigins].filter((s) => s.length > 0))),
        hostnames,
        mcpEnabled,
        mcpInjectIntoAgents,
        mcpDebug: env.MCP_DEBUG === "1",
        agentStoragePath: path.join(paseoHome, "agents"),
        staticDir: "public",
        agentClients: {},
        relayEnabled,
        relayEndpoint,
        relayPublicEndpoint,
        appBaseUrl,
        openai,
        speech,
        voiceLlmProvider,
        voiceLlmProviderExplicit,
        voiceLlmModel,
        agentProviderSettings: extractAgentProviderSettings(providerOverrides),
        providerOverrides,
    };
}
//# sourceMappingURL=config.js.map