import { z } from "zod";
import { formatErrorForMcp } from "../utils/errors.js";
export function registerEditorTools(server, godot) {
    server.tool("get_editor_errors", "Get recent errors and stack traces from the Godot editor log", {
        max_lines: z.number().optional().describe("Maximum log lines to scan for errors (default: 50)"),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("get_editor_errors", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("get_output_log", "Read the full Godot editor Output panel content. Unlike get_editor_errors which filters for errors only, this returns all output including print() statements and warnings.", {
        max_lines: z.number().optional().describe("Maximum number of lines to return from the end (default: 100)"),
        filter: z.string().optional().describe("Filter lines containing this substring (case-sensitive)"),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("get_output_log", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("get_editor_screenshot", "Capture a screenshot of the Godot editor's 2D/3D viewport", {
        save_path: z.string().optional().describe("Optional res:// or user:// path to save the screenshot as PNG file (e.g. 'res://screenshot.png'). When provided, the image is saved to disk and the file path is returned instead of base64 data."),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("get_editor_screenshot", params);
            if (result && typeof result === "object" && "saved_path" in result) {
                return {
                    content: [
                        {
                            type: "text",
                            text: `Screenshot saved: ${result.saved_path} (${result.width}x${result.height})`,
                        },
                    ],
                };
            }
            if (result && typeof result === "object" && "image_base64" in result) {
                return {
                    content: [
                        {
                            type: "image",
                            data: result.image_base64,
                            mimeType: "image/png",
                        },
                        {
                            type: "text",
                            text: `Screenshot captured: ${result.width}x${result.height}`,
                        },
                    ],
                };
            }
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("get_game_screenshot", "Capture a single screenshot of the running game (requires a scene to be playing). Good for checking static visual state (UI layout, scene composition, colors). For verifying animations or movement, use capture_frames instead — a single screenshot cannot confirm whether an animation is playing.", {
        save_path: z.string().optional().describe("Optional res:// or user:// path to save the screenshot as PNG file (e.g. 'res://screenshot.png'). When provided, the image is saved to disk and the file path is returned instead of base64 data."),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("get_game_screenshot", params);
            if (result && typeof result === "object" && "saved_path" in result) {
                return {
                    content: [
                        {
                            type: "text",
                            text: `Game screenshot saved: ${result.saved_path} (${result.width}x${result.height})${result.note ? ` (${result.note})` : ""}`,
                        },
                    ],
                };
            }
            if (result && typeof result === "object" && "image_base64" in result) {
                return {
                    content: [
                        {
                            type: "image",
                            data: result.image_base64,
                            mimeType: "image/png",
                        },
                        {
                            type: "text",
                            text: `Game screenshot: ${result.width}x${result.height}${result.note ? ` (${result.note})` : ""}`,
                        },
                    ],
                };
            }
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("execute_editor_script", "Execute arbitrary GDScript code inside the Godot editor. Use _mcp_print() to output values. By default refuses to execute code that contains direct file/resource write APIs (ResourceSaver.save, FileAccess WRITE, ProjectSettings.save, ConfigFile.save, DirAccess filesystem mutations) because those bypass the per-command open-resource guards. Use the dedicated MCP tools (save_scene, create_script, etc.) for those operations, or pass allow_unsafe_editor_io=true ONLY when you have verified no open editor resource will be overwritten.", {
        code: z.string().describe("GDScript code to execute. Use _mcp_print(value) to capture output. " +
            "The code runs inside a run() function with access to the full editor API."),
        allow_unsafe_editor_io: z.boolean().optional().describe("Override the file-write safety guard. Only set this when you are certain no open scene/script/shader will be overwritten by the script. Prefer the dedicated MCP tools for ordinary save flows."),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("execute_editor_script", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("clear_output", "Clear the Godot editor output panel", {}, async () => {
        try {
            const result = await godot.sendCommand("clear_output");
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("get_signals", "Get all signals of a node, including current connections", {
        node_path: z.string().describe("Path to the node to inspect"),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("get_signals", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("reload_plugin", "Reload the Godot MCP Pro plugin (disable/re-enable). Connection will briefly drop and auto-reconnect. NOTE: This does NOT reload GDScript preload() caches. If you changed GDScript command files, use execute_editor_script with 'EditorInterface.restart_editor(true)' instead for a full editor restart.", {}, async () => {
        try {
            const result = await godot.sendCommand("reload_plugin");
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("reload_project", "Rescan the Godot project filesystem and reload changed scripts (no reconnection needed)", {}, async () => {
        try {
            const result = await godot.sendCommand("reload_project");
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("compare_screenshots", "Compare two screenshots pixel-by-pixel and return a diff analysis. Returns changed pixel count, diff percentage, and a highlighted diff image. Useful for visual regression testing. Accepts file paths (res://, user://) or base64 PNG strings.", {
        image_a: z.string().describe("First image: file path (e.g. 'user://screenshot_a.png') or base64 PNG string"),
        image_b: z.string().describe("Second image: file path (e.g. 'user://screenshot_b.png') or base64 PNG string"),
        threshold: z.number().optional().describe("Color difference threshold (0-255, default: 10). Pixels with max channel difference below this are considered identical."),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("compare_screenshots", params);
            const content = [];
            // Add summary text
            content.push({
                type: "text",
                text: JSON.stringify({
                    identical: result.identical,
                    changed_pixels: result.changed_pixels,
                    total_pixels: result.total_pixels,
                    diff_percentage: result.diff_percentage,
                    threshold: result.threshold,
                    size: `${result.width}x${result.height}`,
                }, null, 2),
            });
            // Add diff image if there are differences
            if (result.diff_image_base64 && !result.identical) {
                content.push({
                    type: "image",
                    data: result.diff_image_base64,
                    mimeType: "image/png",
                });
            }
            return { content };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("set_auto_dismiss", "Enable or disable automatic dismissal of blocking editor dialogs (e.g. 'Reload from disk?', 'Save changes?'). Enable this before operations that modify files externally, and disable when done. Disabled by default.", {
        enabled: z.boolean().describe("true to enable auto-dismiss, false to disable"),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("set_auto_dismiss", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("get_editor_camera", "Get the current 3D editor viewport camera position, rotation, and FOV. Use this to understand the current view before taking editor screenshots.", {}, async () => {
        try {
            const result = await godot.sendCommand("get_editor_camera");
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
    server.tool("set_editor_camera", "Move the 3D editor viewport camera to a specific position and orientation. Use this to frame a view before taking editor screenshots to validate changes visually.", {
        position: z.object({
            x: z.number().describe("X position"),
            y: z.number().describe("Y position"),
            z: z.number().describe("Z position"),
        }).optional().describe("Camera world position"),
        rotation_degrees: z.object({
            x: z.number().describe("Pitch (degrees)"),
            y: z.number().describe("Yaw (degrees)"),
            z: z.number().describe("Roll (degrees)"),
        }).optional().describe("Camera rotation in degrees"),
        look_at: z.object({
            x: z.number().describe("Target X"),
            y: z.number().describe("Target Y"),
            z: z.number().describe("Target Z"),
        }).optional().describe("Point to look at (overrides rotation_degrees if both set)"),
        fov: z.number().optional().describe("Field of view in degrees (default: 75)"),
    }, async (params) => {
        try {
            const result = await godot.sendCommand("set_editor_camera", params);
            return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        }
        catch (e) {
            return { content: [{ type: "text", text: formatErrorForMcp(e) }], isError: true };
        }
    });
}
//# sourceMappingURL=editor-tools.js.map