"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerTools = registerTools;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const logger_1 = require("../../../lib/logger");
const schemas_1 = require("./schemas");
const lifecycle_1 = require("./lifecycle");
// Tool-handler registration for the Playwright MCP server.
function registerTools(srv) {
    // ── navigate ─────────────────────────────────────────────
    srv.registerTool('navigate', {
        title: 'Navigate to URL',
        description: 'Open a URL in a new browser page. Returns the page ID for subsequent tool calls.',
        inputSchema: schemas_1.navigateSchema,
    }, async (args) => {
        const b = await (0, lifecycle_1.ensureBrowser)();
        const page = await b.newPage();
        const id = (0, lifecycle_1.allocatePageId)();
        lifecycle_1.pages.set(id, page);
        await page.goto(args.url, {
            waitUntil: args.wait_until || 'load',
            timeout: 30_000,
        });
        const title = await page.title();
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ page_id: id, url: args.url, title }),
                }],
        };
    });
    // ── screenshot ───────────────────────────────────────────
    srv.registerTool('screenshot', {
        title: 'Take Screenshot',
        description: 'Capture a screenshot of the current page (or a specific element) and save it as a PNG file.',
        inputSchema: schemas_1.screenshotSchema,
    }, async (args) => {
        const page = (0, lifecycle_1.getPage)(args.page_id);
        const pageId = (0, lifecycle_1.getPageId)(args.page_id);
        const dir = path.dirname(args.path);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        if (args.selector) {
            const element = await page.$(args.selector);
            if (!element) {
                return {
                    content: [{
                            type: 'text',
                            text: JSON.stringify({ error: `Element not found: ${args.selector}` }),
                        }],
                    isError: true,
                };
            }
            await element.screenshot({ path: args.path });
        }
        else {
            await page.screenshot({
                path: args.path,
                fullPage: args.full_page ?? false,
            });
        }
        const stats = fs.statSync(args.path);
        logger_1.loggerRegistry.info(`[lt-mcp:playwright] screenshot saved: ${args.path} (${stats.size} bytes)`);
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({
                        page_id: pageId,
                        path: args.path,
                        size_bytes: stats.size,
                        url: page.url(),
                    }),
                }],
        };
    });
    // ── click ────────────────────────────────────────────────
    srv.registerTool('click', {
        title: 'Click Element',
        description: 'Click an element on the page by CSS selector.',
        inputSchema: schemas_1.clickSchema,
    }, async (args) => {
        const page = (0, lifecycle_1.getPage)(args.page_id);
        await page.click(args.selector, { timeout: 10_000 });
        await page.waitForTimeout(500);
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({
                        clicked: args.selector,
                        url: page.url(),
                        title: await page.title(),
                    }),
                }],
        };
    });
    // ── fill ─────────────────────────────────────────────────
    srv.registerTool('fill', {
        title: 'Fill Input',
        description: 'Type a value into an input field by CSS selector. Clears existing content first.',
        inputSchema: schemas_1.fillSchema,
    }, async (args) => {
        const page = (0, lifecycle_1.getPage)(args.page_id);
        await page.fill(args.selector, args.value, { timeout: 10_000 });
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ filled: args.selector, value: args.value }),
                }],
        };
    });
    // ── wait_for ─────────────────────────────────────────────
    srv.registerTool('wait_for', {
        title: 'Wait for Element',
        description: 'Wait for an element to appear on the page. Useful after navigation or async operations.',
        inputSchema: schemas_1.waitForSchema,
    }, async (args) => {
        const page = (0, lifecycle_1.getPage)(args.page_id);
        await page.waitForSelector(args.selector, {
            timeout: args.timeout ?? 10_000,
        });
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ found: args.selector }),
                }],
        };
    });
    // ── evaluate ─────────────────────────────────────────────
    srv.registerTool('evaluate', {
        title: 'Run JavaScript',
        description: 'Evaluate a JavaScript expression in the page context. Returns the serialized result.',
        inputSchema: schemas_1.evaluateSchema,
    }, async (args) => {
        const page = (0, lifecycle_1.getPage)(args.page_id);
        const result = await page.evaluate(args.script);
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ result }),
                }],
        };
    });
    // ── list_pages ───────────────────────────────────────────
    srv.registerTool('list_pages', {
        title: 'List Open Pages',
        description: 'List all open browser pages with their IDs, URLs, and titles.',
        inputSchema: schemas_1.listPagesSchema,
    }, async (_args) => {
        const result = [];
        for (const [id, page] of lifecycle_1.pages) {
            result.push({
                page_id: id,
                url: page.url(),
                title: await page.title(),
            });
        }
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ pages: result, count: result.length }),
                }],
        };
    });
    // ── close_page ───────────────────────────────────────────
    srv.registerTool('close_page', {
        title: 'Close Page',
        description: 'Close a browser page by its ID.',
        inputSchema: schemas_1.closePageSchema,
    }, async (args) => {
        const page = lifecycle_1.pages.get(args.page_id);
        if (!page) {
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({ error: `Page not found: ${args.page_id}` }),
                    }],
                isError: true,
            };
        }
        await page.close();
        lifecycle_1.pages.delete(args.page_id);
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ closed: args.page_id }),
                }],
        };
    });
}
