/**
 * Browser Extension for spectral.
 *
 * Provides native browser automation tools via Playwright, registered as
 * spectral extension tools (not MCP). This enables the coding agent to
 * control a real browser: navigate, click, type, evaluate JS, take
 * screenshots, inspect network traffic, and more.
 *
 * All 20 tools match the same API surface as playwright-mcp, but without
 * the MCP protocol layer — they call Playwright directly from Node.js.
 *
 * Architecture:
 *   - BrowserService (singleton) — one browser, one context, multiple pages
 *   - Tools register via ext.registerTool() — same pattern as kanban-bridge
 *   - Browser auto-closes on session_shutdown
 *
 * Registered tools (20):
 *   Core:        browser_navigate, browser_navigate_back, browser_close, browser_resize
 *   Tabs:        browser_tabs
 *   Input:       browser_click, browser_type, browser_press_key, browser_hover,
 *                browser_drag, browser_select_option, browser_fill_form, browser_file_upload
 *   Evaluate:    browser_evaluate, browser_run_code_unsafe
 *   Screenshot:  browser_take_screenshot, browser_snapshot
 *   Network:     browser_network_requests, browser_network_request
 *   Console:     browser_console_messages
 *   Dialog:      browser_handle_dialog
 *   Wait:        browser_wait_for
 *   Drop:        browser_drop
 *
 * Usage:
 *   spectral --extension ./cli-node/src/extensions/browser/index.ts
 */
import { BrowserService } from "./browser-service.js";
import { registerCoreTools } from "./tools/core.js";
import { registerTabsTools } from "./tools/tabs.js";
import { registerInputTools } from "./tools/input.js";
import { registerEvaluateTools } from "./tools/evaluate.js";
import { registerScreenshotTools } from "./tools/screenshot.js";
import { registerNetworkTools } from "./tools/network.js";
import { registerConsoleTools } from "./tools/console.js";
import { registerDialogTools } from "./tools/dialog.js";
import { registerWaitTools } from "./tools/wait.js";
import { registerDropTools } from "./tools/drop.js";
import { registerStreamTools } from "./stream/stream-tool.js";
export default async function browserExtension(ext) {
    const available = BrowserService.isAvailable();
    if (!available) {
        const reason = BrowserService.unavailabilityReason() ?? "unknown reason";
        process.stderr.write(`[browser] Browser automation unavailable: ${reason}\n` +
            `[browser] Install Playwright to enable browser features: npx playwright install chromium\n`);
        // Extension still loads cleanly — just logs the warning. Tools are not
        // registered, so the agent won't see browser tools and won't attempt to use them.
        return;
    }
    const bs = BrowserService.getInstance();
    // Auto-close browser when the session ends
    ext.on("session_shutdown", async () => {
        try {
            await bs.close();
            process.stderr.write("[browser] Browser closed.\n");
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            process.stderr.write(`[browser] Error closing browser: ${msg}\n`);
        }
    });
    // Register all tool groups
    const registrars = [
        { name: "core", fn: () => registerCoreTools(ext, bs) },
        { name: "tabs", fn: () => registerTabsTools(ext, bs) },
        { name: "input", fn: () => registerInputTools(ext, bs) },
        { name: "evaluate", fn: () => registerEvaluateTools(ext, bs) },
        { name: "screenshot", fn: () => registerScreenshotTools(ext, bs) },
        { name: "network", fn: () => registerNetworkTools(ext, bs) },
        { name: "console", fn: () => registerConsoleTools(ext, bs) },
        { name: "dialog", fn: () => registerDialogTools(ext, bs) },
        { name: "wait", fn: () => registerWaitTools(ext, bs) },
        { name: "drop", fn: () => registerDropTools(ext, bs) },
        { name: "stream", fn: () => registerStreamTools(ext, bs) },
    ];
    let totalRegistered = 0;
    for (const registrar of registrars) {
        try {
            const before = countRegisteredTools(ext);
            registrar.fn();
            const after = countRegisteredTools(ext);
            totalRegistered += after - before;
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            process.stderr.write(`[browser] Failed to register ${registrar.name} tools: ${msg}\n`);
        }
    }
    process.stderr.write(`[browser] Registered ${totalRegistered} browser automation tool(s). ` +
        `Browser: ${bs.getConfig().browserName}, ` +
        `headless: ${bs.getConfig().headless}.\n`);
}
/** Count how many tools are registered (best-effort). */
function countRegisteredTools(ext) {
    try {
        // getToolDefinition is available on ExtensionAPI
        let count = 0;
        const knownTools = [
            "browser_navigate", "browser_navigate_back", "browser_close", "browser_resize",
            "browser_tabs",
            "browser_click", "browser_type", "browser_press_key", "browser_hover",
            "browser_drag", "browser_select_option", "browser_fill_form", "browser_file_upload",
            "browser_evaluate", "browser_run_code_unsafe",
            "browser_take_screenshot", "browser_snapshot",
            "browser_network_requests", "browser_network_request",
            "browser_console_messages",
            "browser_handle_dialog",
            "browser_wait_for",
            "browser_drop",
            "browser_stream_start", "browser_stream_stop", "browser_stream_status",
        ];
        for (const name of knownTools) {
            if (ext.getToolDefinition(name))
                count++;
        }
        return count;
    }
    catch {
        return 0;
    }
}
