/**
 * Stream tools: browser_stream_start, browser_stream_stop, browser_stream_status.
 *
 * These extend the browser extension with WebRTC streaming capability
 * so that remote viewers can watch the browser content in real time.
 */
import { SignalingClient } from "./signaling-client.js";
import { injectStreamingCode, stopStreaming } from "./stream-injector.js";
let activeStream = null;
export function registerStreamTools(ext, bs) {
    const startTool = {
        name: "browser_stream_start",
        label: "Start Browser Stream",
        description: "Start streaming the browser content via WebRTC. " +
            "Returns a sessionId that viewers can use to connect through the backend signaling server. " +
            "The stream uses canvas capture at 15 FPS — not a full screen mirror, but a live visualization. " +
            "Use browser_stream_stop when done.",
        promptSnippet: "`browser_stream_start { url }` — start streaming the browser to viewers",
        parameters: {
            type: "object",
            properties: {
                url: {
                    type: "string",
                    description: "Optional initial URL to navigate to before starting the stream.",
                },
            },
        },
        async execute(_toolCallId, params) {
            const p = params;
            if (activeStream) {
                return {
                    content: [{
                            type: "text",
                            text: `Stream already active (session: ${activeStream.sessionId}). Use browser_stream_stop first.`,
                        }],
                    details: { isError: true },
                };
            }
            try {
                const { page } = await bs.ensureBrowser();
                if (p.url) {
                    await bs.navigate(p.url);
                }
                const signalingUrl = process.env.SPECTRAL_STREAM_SIGNALING_URL ?? "ws://localhost:4008/browser-stream";
                const sessionId = crypto.randomUUID();
                const iceServers = [
                    { urls: "stun:stun.l.google.com:19302" },
                    { urls: "stun:stun1.l.google.com:19302" },
                    ...(process.env.SPECTRAL_TURN_URL
                        ? [{
                                urls: process.env.SPECTRAL_TURN_URL,
                                username: process.env.SPECTRAL_TURN_USERNAME ?? "",
                                credential: process.env.SPECTRAL_TURN_CREDENTIAL ?? "",
                            }]
                        : []),
                ];
                const signalingClient = new SignalingClient({
                    signalingUrl,
                    sessionId,
                    iceServers,
                });
                await signalingClient.connect();
                await injectStreamingCode(page, {
                    signalingUrl,
                    sessionId,
                    iceServers: [
                        { urls: "stun:stun.l.google.com:19302" },
                    ],
                });
                activeStream = {
                    sessionId,
                    signalingClient,
                    startedAt: Date.now(),
                };
                return {
                    content: [{
                            type: "text",
                            text: [
                                `✓ Browser stream started`,
                                `Session ID: ${sessionId}`,
                                `Signaling URL: ${signalingUrl}`,
                                ``,
                                `Viewers connect via: ${signalingUrl}?session=${sessionId}`,
                                ``,
                                `Use these tools to control the stream:`,
                                `- browser_stream_stop: stop streaming`,
                                `- browser_stream_status: check stream status`,
                                `- browser_navigate: navigate to a different URL`,
                                `- browser_evaluate: execute JS in the streamed page`,
                            ].join("\n"),
                        }],
                    details: { sessionId },
                };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return {
                    content: [{ type: "text", text: `Failed to start browser stream: ${msg}` }],
                    details: { isError: true },
                };
            }
        },
    };
    const stopTool = {
        name: "browser_stream_stop",
        label: "Stop Browser Stream",
        description: "Stop the active browser stream and clean up WebRTC connections.",
        promptSnippet: "`browser_stream_stop` — stop the active browser stream",
        parameters: {
            type: "object",
            properties: {},
        },
        async execute() {
            if (!activeStream) {
                return {
                    content: [{ type: "text", text: "No active stream." }],
                    details: {},
                };
            }
            try {
                const page = bs.getActivePage();
                await stopStreaming(page);
            }
            catch { /* ignore page-level errors */ }
            try {
                activeStream.signalingClient.close();
            }
            catch { /* ignore */ }
            const duration = Math.round((Date.now() - activeStream.startedAt) / 1000);
            const sessionId = activeStream.sessionId;
            activeStream = null;
            return {
                content: [{
                        type: "text",
                        text: `✓ Stream stopped.\nSession: ${sessionId}\nDuration: ${duration}s`,
                    }],
                details: {},
            };
        },
    };
    const statusTool = {
        name: "browser_stream_status",
        label: "Browser Stream Status",
        description: "Check the status of the current browser stream.",
        promptSnippet: "`browser_stream_status` — check stream status",
        parameters: {
            type: "object",
            properties: {},
        },
        async execute() {
            if (!activeStream) {
                return {
                    content: [{ type: "text", text: "No active stream. Use browser_stream_start to begin." }],
                    details: {},
                };
            }
            const duration = Math.round((Date.now() - activeStream.startedAt) / 1000);
            return {
                content: [{
                        type: "text",
                        text: [
                            `Stream active`,
                            `Session ID: ${activeStream.sessionId}`,
                            `Started: ${new Date(activeStream.startedAt).toISOString()}`,
                            `Duration: ${duration}s`,
                            `Signaling: ${activeStream.signalingClient.isConnected() ? "connected" : "disconnected"}`,
                        ].join("\n"),
                    }],
                details: {},
            };
        },
    };
    for (const tool of [startTool, stopTool, statusTool]) {
        try {
            ext.registerTool(tool);
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            process.stderr.write(`[browser-stream] Failed to register ${tool.name}: ${msg}\n`);
        }
    }
}
