"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleInput = handleInput;
const logger_1 = require("../logger");
const log = (0, logger_1.modLogger)('browser-chrome:input');
// Whitelist of modifier names accepted from the client. Anything else is
// silently dropped — defends against bogus values being passed straight
// to playwright's keyboard API.
const VALID_MODIFIERS = ['Shift', 'Control', 'Alt', 'Meta'];
const VALID_BUTTONS = ['left', 'right', 'middle'];
function clamp(n, min, max) {
    if (!Number.isFinite(n))
        return min;
    return Math.max(min, Math.min(max, Math.round(n)));
}
function sanitizeModifiers(arr) {
    if (!Array.isArray(arr))
        return [];
    return arr.filter((m) => VALID_MODIFIERS.includes(m));
}
function sanitizeButton(b) {
    return VALID_BUTTONS.includes(b ?? '') ? b : 'left';
}
async function handleInput(session, msg) {
    session.lastActivityAt = Date.now();
    switch (msg.type) {
        case 'click': {
            const x = clamp(msg.x, 0, session.viewport.w);
            const y = clamp(msg.y, 0, session.viewport.h);
            const mods = sanitizeModifiers(msg.modifiers);
            for (const m of mods)
                await session.page.keyboard.down(m);
            try {
                await session.page.mouse.click(x, y, { button: sanitizeButton(msg.button) });
            }
            finally {
                for (const m of [...mods].reverse())
                    await session.page.keyboard.up(m).catch(() => { });
            }
            break;
        }
        case 'mousemove': {
            const x = clamp(msg.x, 0, session.viewport.w);
            const y = clamp(msg.y, 0, session.viewport.h);
            await session.page.mouse.move(x, y);
            break;
        }
        case 'scroll': {
            const x = clamp(msg.x, 0, session.viewport.w);
            const y = clamp(msg.y, 0, session.viewport.h);
            await session.page.mouse.move(x, y);
            await session.page.mouse.wheel(clamp(msg.deltaX, -10000, 10000), clamp(msg.deltaY, -10000, 10000));
            break;
        }
        case 'key': {
            if (typeof msg.key !== 'string' || msg.key.length === 0 || msg.key.length > 32)
                return;
            const mods = sanitizeModifiers(msg.modifiers);
            // Hold modifiers, perform key action, release modifiers (in reverse).
            for (const m of mods)
                await session.page.keyboard.down(m);
            try {
                if (msg.action === 'down')
                    await session.page.keyboard.down(msg.key);
                else if (msg.action === 'up')
                    await session.page.keyboard.up(msg.key);
                else
                    await session.page.keyboard.press(msg.key);
            }
            finally {
                for (const m of [...mods].reverse())
                    await session.page.keyboard.up(m).catch(() => { });
            }
            break;
        }
        case 'type': {
            if (typeof msg.text !== 'string' || msg.text.length === 0 || msg.text.length > 1000)
                return;
            await session.page.keyboard.type(msg.text);
            break;
        }
        case 'resize': {
            const w = clamp(msg.w, 200, 3840);
            const h = clamp(msg.h, 200, 2160);
            await session.page.setViewportSize({ width: w, height: h });
            session.viewport = { w, h };
            log.info({ sid: session.sid, w, h }, 'viewport resized');
            break;
        }
    }
}
//# sourceMappingURL=input-forwarder.js.map