import { logger } from "./logger.js";
export class McpLifecycleManager {
    manager;
    keepAliveServers = new Map();
    allServers = new Map();
    serverSettings = new Map();
    globalIdleTimeout = 10 * 60 * 1000;
    healthCheckInterval;
    onReconnect;
    onIdleShutdown;
    constructor(manager) {
        this.manager = manager;
    }
    /**
     * Set callback to be invoked after a successful auto-reconnect.
     * Use this to update tool metadata when a server reconnects.
     */
    setReconnectCallback(callback) {
        this.onReconnect = callback;
    }
    markKeepAlive(name, definition) {
        this.keepAliveServers.set(name, definition);
    }
    registerServer(name, definition, settings) {
        this.allServers.set(name, definition);
        if (settings?.idleTimeout !== undefined) {
            this.serverSettings.set(name, settings);
        }
    }
    setGlobalIdleTimeout(minutes) {
        this.globalIdleTimeout = minutes * 60 * 1000;
    }
    setIdleShutdownCallback(callback) {
        this.onIdleShutdown = callback;
    }
    startHealthChecks(intervalMs = 30000) {
        this.healthCheckInterval = setInterval(() => {
            this.checkConnections();
        }, intervalMs);
        this.healthCheckInterval.unref();
    }
    async checkConnections() {
        for (const [name, definition] of this.keepAliveServers) {
            const connection = this.manager.getConnection(name);
            if (!connection || connection.status !== "connected") {
                try {
                    await this.manager.connect(name, definition);
                    logger.debug(`Reconnected to ${name}`);
                    // Notify extension to update metadata
                    this.onReconnect?.(name);
                }
                catch (error) {
                    console.error(`MCP: Failed to reconnect to ${name}:`, error);
                }
            }
        }
        for (const [name] of this.allServers) {
            if (this.keepAliveServers.has(name))
                continue;
            const timeout = this.getIdleTimeout(name);
            if (timeout > 0 && this.manager.isIdle(name, timeout)) {
                await this.manager.close(name);
                this.onIdleShutdown?.(name);
            }
        }
    }
    getIdleTimeout(name) {
        const perServer = this.serverSettings.get(name)?.idleTimeout;
        if (perServer !== undefined)
            return perServer * 60 * 1000;
        return this.globalIdleTimeout;
    }
    async gracefulShutdown() {
        if (this.healthCheckInterval) {
            clearInterval(this.healthCheckInterval);
        }
        await this.manager.closeAll();
    }
}
