import { JsonRpcErrorCode, McpError } from '../../types-global/errors.js';
import { ErrorHandler } from '../../utils/internal/error-handler/errorHandler.js';
import { measurePromptGeneration } from '../../utils/internal/performance.js';
import { requestContextService } from '../../utils/internal/requestContext.js';
export class PromptRegistry {
    promptDefs;
    logger;
    /** Tracks registered prompt names to detect duplicates at startup. */
    registeredNames = new Set();
    constructor(promptDefs, logger) {
        this.promptDefs = promptDefs;
        this.logger = logger;
    }
    /**
     * Registers all prompts on the given MCP server.
     */
    async registerAll(server) {
        this.registeredNames.clear();
        const context = requestContextService.createRequestContext({
            operation: 'PromptRegistry.registerAll',
        });
        this.logger.debug(`Registering ${this.promptDefs.length} prompt(s)...`, context);
        // The SDK only initializes prompts/list + prompts/get handlers when a
        // prompt is first registered. Initialize them up front so empty servers
        // still expose truthful MCP prompt behavior.
        server.setPromptRequestHandlers();
        for (const promptDef of this.promptDefs) {
            await this.registerPrompt(server, promptDef, context);
        }
        this.logger.debug(`Successfully registered ${this.promptDefs.length} prompts`, context);
    }
    /** Throws at startup if a prompt with the same name was already registered. */
    assertUniqueName(name) {
        if (this.registeredNames.has(name)) {
            throw new Error(`Duplicate prompt name '${name}': a prompt with this name is already registered. ` +
                'Each prompt must have a unique name.');
        }
        this.registeredNames.add(name);
    }
    async registerPrompt(server, promptDef, context) {
        this.logger.debug(`Registering prompt: ${promptDef.name}`, context);
        this.assertUniqueName(promptDef.name);
        await ErrorHandler.tryCatch(() => {
            server.registerPrompt(promptDef.name, {
                ...(promptDef.title && { title: promptDef.title }),
                description: promptDef.description,
                ...(promptDef.args && {
                    argsSchema: promptDef.args.shape,
                }),
            }, async (args) => {
                try {
                    const validatedArgs = promptDef.args ? promptDef.args.parse(args) : args;
                    const messages = await measurePromptGeneration(() => Promise.resolve(promptDef.generate(validatedArgs)), { ...context, promptName: promptDef.name }, validatedArgs);
                    return { messages };
                }
                catch (error) {
                    const handled = ErrorHandler.handleError(error, {
                        operation: `prompt:${promptDef.name}`,
                        context,
                    });
                    throw handled instanceof McpError
                        ? handled
                        : new McpError(JsonRpcErrorCode.InternalError, handled.message);
                }
            });
            this.logger.debug(`Registered prompt: ${promptDef.name}`, context);
        }, {
            operation: `RegisteringPrompt_${promptDef.name}`,
            context,
            errorCode: JsonRpcErrorCode.InitializationFailed,
            critical: true,
        });
    }
}
//# sourceMappingURL=prompt-registration.js.map