import { Type as T } from "typebox";
import { resolvePath } from "../../utils/paths.js";
import { getLSPService } from "../lsp/index.js";
const LspInput = T.Union([
    T.Object({
        command: T.Literal("hover"),
        filePath: T.String({ description: "Path to the file" }),
        line: T.Integer({ description: "Line number (0-based)" }),
        column: T.Integer({ description: "Column number (0-based)" }),
    }),
    T.Object({
        command: T.Literal("definition"),
        filePath: T.String({ description: "Path to the file" }),
        line: T.Integer({ description: "Line number (0-based)" }),
        column: T.Integer({ description: "Column number (0-based)" }),
    }),
    T.Object({
        command: T.Literal("references"),
        filePath: T.String({ description: "Path to the file" }),
        line: T.Integer({ description: "Line number (0-based)" }),
        column: T.Integer({ description: "Column number (0-based)" }),
    }),
    T.Object({
        command: T.Literal("symbols"),
        filePath: T.String({ description: "Path to the file" }),
    }),
]);
export function createLspToolDefinition(cwd) {
    return {
        name: "lsp",
        label: "LSP",
        description: "Query language intelligence via LSP: hover for info, definition for jump-to-source, references for usages, symbols for file outline.",
        parameters: LspInput,
        renderShell: "default",
        promptSnippet: "lsp: query code intelligence via LSP (hover, definition, references, symbols)",
        promptGuidelines: [
            "Use `lsp` with command `hover` before editing code you're unfamiliar with to understand symbol types and signatures.",
        ],
        async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
            const _resolvedCwd = resolvePath(cwd);
            try {
                switch (params.command) {
                    case "hover": {
                        const result = await getLSPService().hover(params.filePath, params.line, params.column);
                        if (!result) {
                            return {
                                content: [
                                    {
                                        type: "text",
                                        text: "No hover information available (LSP not available for this file type).",
                                    },
                                ],
                                details: null,
                            };
                        }
                        return {
                            content: [{ type: "text", text: result.contents }],
                            details: null,
                        };
                    }
                    case "definition": {
                        const result = await getLSPService().definition(params.filePath, params.line, params.column);
                        if (!result || result.length === 0) {
                            return {
                                content: [{ type: "text", text: "No definition found." }],
                                details: null,
                            };
                        }
                        const lines = result.map((loc) => `${loc.uri}:${loc.line + 1}:${loc.column + 1}`);
                        return {
                            content: [{ type: "text", text: `Definition(s):\n${lines.join("\n")}` }],
                            details: result,
                        };
                    }
                    case "references": {
                        const result = await getLSPService().references(params.filePath, params.line, params.column);
                        if (!result || result.length === 0) {
                            return {
                                content: [{ type: "text", text: "No references found." }],
                                details: null,
                            };
                        }
                        const lines = result.map((loc) => `${loc.uri}:${loc.line + 1}:${loc.column + 1}`);
                        return {
                            content: [{ type: "text", text: `References (${result.length}):\n${lines.join("\n")}` }],
                            details: result,
                        };
                    }
                    case "symbols": {
                        const result = await getLSPService().documentSymbols(params.filePath);
                        if (!result || result.length === 0) {
                            return {
                                content: [{ type: "text", text: "No symbols found in file." }],
                                details: null,
                            };
                        }
                        const lines = result.map((sym) => `${"  ".repeat(sym.kind >= 4 ? 1 : 0)}${sym.name} (line ${sym.line + 1})`);
                        return {
                            content: [{ type: "text", text: `Symbols in file:\n${lines.join("\n")}` }],
                            details: result,
                        };
                    }
                }
            }
            catch (error) {
                return {
                    content: [
                        { type: "text", text: `LSP error: ${error instanceof Error ? error.message : String(error)}` },
                    ],
                    details: null,
                };
            }
        },
    };
}
//# sourceMappingURL=lsp.js.map