import { LSPConnection } from "./LSPConnection.js";
/**
 * LSPManager - Manages external language servers for advanced code intelligence.
 */
export class LSPManager {
    connections = new Map(); // extension -> connection
    /**
     * Initialize a language server for a specific file extension.
     */
    async initServer(extension, command, args) {
        if (this.connections.has(extension))
            return;
        try {
            const connection = new LSPConnection(command, args);
            this.connections.set(extension, connection);
            // Standard LSP initialization
            await connection.sendRequest("initialize", {
                processId: process.pid,
                capabilities: Object.create(null),
                rootUri: null,
            });
            connection.sendNotification("initialized", Object.create(null));
        }
        catch (_error) {
            // Silently swallow — LSP init failure is non-fatal
        }
    }
    /**
     * Send a request to the appropriate LSP server.
     */
    async sendRequest(bash, request) {
        const ext = request.filePath.split(".").pop() || "";
        const connection = this.connections.get(ext);
        if (!connection) {
            // Fallback to internal SemanticEngine if no LSP server is available
            return this.fallbackToSemanticEngine(bash, request);
        }
        try {
            return await connection.sendRequest(request.method, request.params);
        }
        catch (_error) {
            // Silently swallow — caller receives null as the fallback
            return null;
        }
    }
    /**
     * Send a notification to the appropriate LSP server.
     */
    sendNotification(filePath, method, params) {
        const ext = filePath.split(".").pop() || "";
        const connection = this.connections.get(ext);
        if (connection) {
            connection.sendNotification(method, params);
        }
    }
    /**
     * Notify the language server that a file has changed.
     */
    notifyDidChange(filePath, content) {
        this.sendNotification(filePath, "textDocument/didChange", {
            textDocument: {
                uri: `file://${filePath}`,
                version: Date.now(), // Simplified versioning
            },
            contentChanges: [{ text: content }],
        });
    }
    async fallbackToSemanticEngine(bash, request) {
        const engine = bash.semanticEngine;
        if (!engine)
            return null;
        const params = request.params;
        const symbolName = params?.symbolName || "";
        switch (request.method) {
            case "textDocument/definition":
                return engine.findDefinition(symbolName);
            case "textDocument/references":
                return engine.getOccurrences(symbolName);
            case "textDocument/documentSymbol":
                return engine.getAllSymbols?.() ?? null;
            case "callHierarchy/incomingCalls": {
                const occurrences = engine.getOccurrences(symbolName);
                if (!occurrences)
                    return null;
                return Array.isArray(occurrences) ? occurrences : null;
            }
            default:
                return null;
        }
    }
}
