/**
 * Registers all Playwright browser tools (+ skyramp_export_zip) as passthrough
 * tools in the Skyramp MCP server, delegating calls to PlaywrightTraceService.
 */
import { z } from "zod";
import { logger } from "../utils/logger.js";
import { PlaywrightTraceService, } from "./PlaywrightTraceService.js";
let _service = null;
export function getPlaywrightTraceService() {
    return _service;
}
export async function registerPlaywrightTools(server, options) {
    _service = new PlaywrightTraceService(options);
    try {
        await _service.initialize();
    }
    catch (error) {
        const msg = error instanceof Error ? error.message : String(error);
        logger.error(`Failed to initialize Playwright tools — browser tools will not be available: ${msg}`);
        _service = null;
        return;
    }
    const tools = _service.getTools();
    logger.info(`Registering ${tools.length} Playwright browser tools`);
    // Only expose essential browser tools to reduce LLM confusion.
    // The full set (23 tools) overwhelms the LLM and causes it to use
    // browser_evaluate/browser_run_code instead of the simpler tools.
    //
    // The DOM Analyzer group (browser_blueprint*, browser_sitemap_*,
    // browser_widget_contract_lookup) is referenced by skyramp_testbot's
    // Task 1 UI Recommendation Grounding and Task 2 capture-act-capture
    // discipline. Omitting them here would silently make the prompt's
    // instructions uncallable.
    const ESSENTIAL_TOOLS = new Set([
        'browser_navigate',
        'browser_snapshot',
        'browser_click',
        'browser_type',
        'browser_press_key',
        'browser_select_option',
        'browser_hover',
        'browser_drag',
        'browser_tabs',
        'browser_navigate_back',
        'browser_wait_for',
        'browser_take_screenshot',
        'browser_assert',
        'skyramp_export_zip',
        // DOM Analyzer tools (Phase C)
        'browser_blueprint',
        'browser_blueprint_diff',
        'browser_sitemap_build',
        'browser_sitemap_query',
        'browser_widget_contract_lookup',
    ]);
    const filteredTools = tools.filter((t) => ESSENTIAL_TOOLS.has(t.name));
    logger.info(`Filtering to ${filteredTools.length} essential tools (from ${tools.length} total)`);
    for (const tool of filteredTools) {
        const zodSchema = jsonSchemaToZod(tool.inputSchema);
        server.registerTool(tool.name, {
            description: tool.description || `Playwright tool: ${tool.name}`,
            inputSchema: zodSchema,
        }, async (params) => {
            if (!_service?.isInitialized()) {
                return {
                    content: [
                        {
                            type: "text",
                            text: "### Error\nPlaywright browser tools are not available. The service failed to initialize.",
                        },
                    ],
                    isError: true,
                };
            }
            return _service.callTool(tool.name, params);
        });
    }
    logger.info(`Registered ${filteredTools.length} Playwright tools: ${filteredTools.map((t) => t.name).join(", ")}`);
}
function jsonSchemaToZod(schema) {
    const properties = schema.properties || {};
    const required = new Set(schema.required || []);
    const shape = {};
    for (const [key, prop] of Object.entries(properties)) {
        let field;
        switch (prop.type) {
            case "string":
                field = prop.enum
                    ? z.enum(prop.enum)
                    : z.string();
                break;
            case "number":
            case "integer":
                field = z.number();
                break;
            case "boolean":
                field = z.boolean();
                break;
            case "array":
                field = z.array(prop.items ? jsonSchemaPropertyToZod(prop.items) : z.unknown());
                break;
            default:
                field = z.unknown();
        }
        if (prop.description)
            field = field.describe(prop.description);
        if (prop.default !== undefined)
            field = field.default(prop.default);
        if (!required.has(key))
            field = field.optional();
        shape[key] = field;
    }
    return z.object(shape);
}
function jsonSchemaPropertyToZod(prop) {
    switch (prop.type) {
        case "string":
            return prop.enum
                ? z.enum(prop.enum)
                : z.string();
        case "number":
        case "integer":
            return z.number();
        case "boolean":
            return z.boolean();
        case "array":
            return z.array(prop.items ? jsonSchemaPropertyToZod(prop.items) : z.unknown());
        default:
            return z.unknown();
    }
}
