/**
 * MCP server provider assembly — builds Promptfoo provider configs.
 */
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
/** Default max tool rounds for MCP multi-turn execution */
export const DEFAULT_MAX_TOOL_ROUNDS = 5;
/** Provider path relative to eval package dist */
export const MCP_PROVIDER_PATH = "file://dist/pipeline/compiler/mode-handlers/mcp-tool-provider/index.js";
// ---------------------------------------------------------------------------
// Provider assembly
// ---------------------------------------------------------------------------
/**
 * Build custom MCP tool provider configs — one per model.
 *
 * Each provider uses the custom mcp-tool-provider.ts which implements a
 * multi-turn tool execution loop. The LLM receives a prompt, discovers
 * MCP tools, calls them, gets results, and continues until it produces
 * a final text answer or exhausts maxToolRounds.
 *
 * Config shape passed to the custom provider:
 *   { model, mcpServer: { url, auth, name }, mcpTools, maxToolRounds, temperature, ... }
 */
export function buildMCPProvider(task, models, warnings) {
    // Build the MCP server config
    const mcpServer = buildMCPServerConfig(task, warnings);
    const mcpTools = task.capabilities ?? undefined;
    const maxToolRounds = task.maxToolRounds ?? DEFAULT_MAX_TOOL_ROUNDS;
    // Helper to build a provider entry for a given model
    function makeProvider(modelId, label, modelConfig) {
        return {
            id: MCP_PROVIDER_PATH,
            label: `${label} + MCP`,
            config: {
                model: modelId,
                mcpServer,
                ...(mcpTools ? { mcpTools } : {}),
                maxToolRounds,
                ...(modelConfig ?? {}),
            },
        };
    }
    // Task-level model override takes precedence over registry models
    const taskModels = task.models;
    if (taskModels && taskModels.length > 0) {
        return taskModels.map((modelId) => makeProvider(modelId, modelId));
    }
    // Use registry models (already filtered to mcp-server mode)
    if (models.length === 0) {
        warnings.push(`MCP task "${task.id}": no models available. Add "mcp-server" to a ` +
            "model's modes array in config/models.ts, or set models on the task.");
        return [
            makeProvider("anthropic:messages:claude-sonnet-4-6", "Claude Sonnet 4.6"),
        ];
    }
    return models.map((model) => makeProvider(model.id, model.label, model.config));
}
/**
 * Build the MCP server connection config for the custom provider.
 *
 * Shape: { url?, command?, name?, auth? }
 * The custom mcp-tool-provider.ts uses this to connect to the MCP server.
 */
export function buildMCPServerConfig(task, warnings) {
    const config = task.serverConfig;
    if (!config) {
        warnings.push(`MCP task "${task.id}": no serverConfig — using placeholder. ` +
            "Set serverConfig.command or serverConfig.url to point to your MCP server.");
        return { name: task.id };
    }
    const serverConfig = { name: task.id };
    if (config.transport === "stdio") {
        serverConfig.command = config.command;
    }
    else {
        serverConfig.url = config.url;
    }
    // Explicit headers for HTTP transports
    if (config.headers) {
        serverConfig.headers = config.headers;
    }
    // Auth config
    if (config.auth) {
        serverConfig.auth = config.auth;
    }
    else if (config.env) {
        const tokenKey = Object.keys(config.env).find((k) => /token|auth|key/i.test(k));
        if (tokenKey) {
            const val = config.env[tokenKey];
            let envVar = val;
            if (val.startsWith("$env(") && val.endsWith(")")) {
                envVar = val.slice(5, -1);
            }
            if (!envVar || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(envVar)) {
                warnings.push(`MCP task: env var name "${envVar}" from "${val}" is not a valid ` +
                    "identifier — skipping auth config");
            }
            else {
                serverConfig.auth = {
                    type: "bearer",
                    token: `{{env.${envVar}}}`,
                };
            }
        }
    }
    return serverConfig;
}
