import { PluginSetupError, PromptTransformError } from "./errors.js";
import { PluginApiImpl } from "./plugin-api-impl.js";
import { assertValidToolName } from "./tool-names.js";
export async function runPluginSetup(plugins, runContext) {
    for (const plugin of plugins) {
        const contributor = `plugin: ${plugin.name}`;
        const api = new PluginApiImpl(runContext, contributor);
        let setupError;
        try {
            for (const tool of plugin.tools ?? []) {
                assertValidToolName(tool.name, contributor);
                runContext.tools.register(tool);
            }
            if (plugin.prompt) {
                runContext.prompts.addTransform(async (ctx) => {
                    try {
                        return await plugin.prompt(ctx);
                    }
                    catch (error) {
                        throw new PromptTransformError(plugin.name, error);
                    }
                });
            }
            runContext.hooks.add(plugin);
            if (plugin.setup) {
                await plugin.setup(api);
            }
            await api.flushSetup();
            if (plugin.dispose) {
                runContext.registerDisposeHook(async () => {
                    await plugin.dispose();
                });
            }
        }
        catch (error) {
            setupError = error;
        }
        if (setupError === undefined) {
            continue;
        }
        const finalSetupError = await settleMcpSetupError(api, setupError);
        try {
            await runContext.dispose();
        }
        catch (disposeError) {
            throw new PluginSetupError(plugin.name, new AggregateError([finalSetupError, disposeError], `Plugin setup/disposal failed for "${plugin.name}".`));
        }
        throw new PluginSetupError(plugin.name, finalSetupError);
    }
}
async function settleMcpSetupError(api, setupError) {
    try {
        await api.flushSetup();
        return setupError;
    }
    catch (mcpSetupError) {
        if (mcpSetupError === setupError) {
            return setupError;
        }
        return new AggregateError([setupError, mcpSetupError], "Plugin setup and MCP discovery both failed.");
    }
}
