// tools/render-spec-for-provider.ts — SPEC-670: MCP tool handler.
//
// Renders the canonical (unified per SPEC-630) `spec.md` for any LLM provider.
// Auto-detects via SPEC-645 client detection when the `provider` argument is omitted.
import { z } from 'zod';
import { hashProjectPath } from '../storage/index.js';
import { detectLLMClient } from '../engine/client-detection.js';
import { getRegisteredProviders, getRenderer, llmClientToProvider, } from '../engine/provider-adapters/registry.js';
import { loadSpecForRendering } from '../engine/provider-adapters/shared/spec-loader.js';
import { compactError, compactResult, formatKeyValue } from './output-formatter.js';
import { SpecIdSchema } from './schemas/index.js';
const PROVIDER_VALUES = ['claude', 'gpt4', 'gemini', 'markdown'];
export const RenderSpecForProviderInputSchema = z.object({
    specId: SpecIdSchema.describe('Spec identifier, e.g. "SPEC-670"'),
    projectPath: z.string().describe('Absolute path to the project root'),
    provider: z
        .enum(PROVIDER_VALUES)
        .optional()
        .describe("Target LLM provider. Valid: 'claude' (MCP + model hints + mcp__planu__ callouts), 'gpt4' (AGENTS.md compatible), 'gemini' (GEMINI.md with function declarations), 'markdown' (≤800-token plain context written to planu/context.md). Omit to auto-detect via SPEC-645 client detection."),
});
export async function handleRenderSpecForProvider(params) {
    // Pre-Zod check: surface the actionable "Unknown provider" message (Scenario 9)
    // when callers pass a string that is not in the registered enum.
    const rawProvider = params.provider;
    if (typeof rawProvider === 'string' &&
        !PROVIDER_VALUES.includes(rawProvider)) {
        const known = getRegisteredProviders().join(', ');
        return compactError(`Unknown provider "${rawProvider}". Registered: ${known}. ` +
            `Add an adapter at src/engine/provider-adapters/adapters/${rawProvider}.ts to support it.`);
    }
    const parsed = RenderSpecForProviderInputSchema.safeParse(params);
    if (!parsed.success) {
        return compactError(`Invalid input for render_spec_for_provider: ${parsed.error.message}. ` +
            `Required: specId (string), projectPath (string). Optional: provider (one of ${PROVIDER_VALUES.join(', ')}).`);
    }
    const { specId, projectPath } = parsed.data;
    let provider = parsed.data.provider;
    // Scenario 6: auto-detect when omitted.
    if (provider === undefined) {
        try {
            const detected = await detectLLMClient(projectPath);
            provider = llmClientToProvider(detected);
        }
        catch {
            provider = 'markdown';
        }
    }
    const projectId = hashProjectPath(projectPath);
    let loadedSpec;
    try {
        loadedSpec = await loadSpecForRendering(projectId, projectPath, specId);
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return compactError(`Cannot load spec for rendering: ${msg}`);
    }
    let renderer;
    try {
        renderer = await getRenderer(provider);
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return compactError(msg);
    }
    let output;
    try {
        output = await renderer.render({ loadedSpec, projectPath });
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return compactError(`Renderer "${provider}" failed: ${msg}`);
    }
    const summary = formatKeyValue({
        provider: output.provider,
        tokenEstimate: output.tokenEstimate,
        filePath: output.filePath ?? '(in-response only)',
        warnings: loadedSpec.warnings.length > 0 ? loadedSpec.warnings.join('; ') : '(none)',
    }, `Rendered ${specId} for ${output.provider}`);
    const result = compactResult(`${summary}\n\n---\n\n${output.content}`);
    result.structuredContent = {
        provider: output.provider,
        specId,
        tokenEstimate: output.tokenEstimate,
        content: output.content,
        filePath: output.filePath,
        extras: { ...output.extras, warnings: loadedSpec.warnings },
        ...(provider === 'claude'
            ? {
                model: loadedSpec.spec.model ?? 'sonnet',
                modelHint: loadedSpec.spec.model ?? 'sonnet',
                budget: loadedSpec.spec.budget ?? 2000,
                toolCallouts: output.extras?.toolCallouts ?? [],
            }
            : {}),
    };
    return result;
}
//# sourceMappingURL=render-spec-for-provider.js.map