"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.CHROMIUM_ARGS = exports.INTERACTIVE_CHROMIUM_ARGS = exports.HEADLESS_CHROMIUM_ARGS = void 0;
exports.setPlaywrightLoader = setPlaywrightLoader;
exports.createPlaywrightLaunchError = createPlaywrightLaunchError;
exports.withChromiumPage = withChromiumPage;
exports.launchPersistentChromiumContext = launchPersistentChromiumContext;
const node_url_1 = require("node:url");
const TOOL_NAME = 'playdrop';
const COMMON_CHROMIUM_ARGS = [
    '--no-sandbox',
    '--disable-web-security',
];
// Force software WebGL for headless capture so local preview output stays stable.
exports.HEADLESS_CHROMIUM_ARGS = [
    ...COMMON_CHROMIUM_ARGS,
    '--use-gl=angle',
    '--use-angle=swiftshader',
    '--enable-unsafe-swiftshader',
    '--ignore-gpu-blocklist',
];
// Visible dev-browser sessions should use the normal GPU path instead of SwiftShader.
exports.INTERACTIVE_CHROMIUM_ARGS = [
    ...COMMON_CHROMIUM_ARGS,
    '--ignore-gpu-blocklist',
];
// Backward-compatible alias for older imports.
exports.CHROMIUM_ARGS = exports.HEADLESS_CHROMIUM_ARGS;
let customLoader = null;
const nativeImport = new Function('specifier', 'return import(specifier);');
function setPlaywrightLoader(loader) {
    customLoader = loader;
}
async function loadPlaywright() {
    if (customLoader) {
        return customLoader();
    }
    const loaderPath = process.env.PLAYDROP_PLAYWRIGHT_LOADER_PATH?.trim();
    if (loaderPath) {
        const loaderModule = await nativeImport((0, node_url_1.pathToFileURL)(loaderPath).href);
        const candidate = loaderModule.loadPlaywright
            ?? loaderModule.createPlaywrightModule
            ?? loaderModule.default
            ?? loaderModule;
        if (typeof candidate === 'function') {
            return await candidate();
        }
        if (candidate && typeof candidate === 'object' && typeof candidate.chromium?.launch === 'function') {
            return candidate;
        }
        throw new Error(`Invalid Playwright loader module at ${loaderPath}.`);
    }
    return Promise.resolve().then(() => __importStar(require('playwright-core')));
}
function createPlaywrightLaunchError(tool, error) {
    const message = error && typeof error === 'object' && 'message' in error ? String(error.message) : String(error);
    if (/browserType\.launch/i.test(message) || /Chromium/i.test(message)) {
        return new Error([
            `[${tool}] Failed to launch Playwright Chromium.`,
            '',
            'Required setup:',
            '  1. npx playwright install chromium',
            '  2. On macOS: xattr -dr com.apple.quarantine "$HOME/Library/Caches/ms-playwright"',
            '  3. If the issue persists, rerun the command with elevated privileges or outside sandboxed contexts.',
            '',
            `Original error: ${message}`,
        ].join('\n'));
    }
    return error instanceof Error ? error : new Error(message);
}
async function grantAutomationLocalNetworkAccess(context, origin) {
    if (!origin?.trim()) {
        return;
    }
    const grantPermissions = context.grantPermissions;
    if (typeof grantPermissions !== 'function') {
        return;
    }
    try {
        await grantPermissions.call(context, ['local-network-access'], { origin });
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        console.warn(`[${TOOL_NAME}] Failed to grant Playwright local-network-access for ${origin}: ${message}`);
    }
}
async function withChromiumPage(callback, options = {}) {
    const { chromium } = await loadPlaywright();
    let browser;
    try {
        browser = await chromium.launch({ headless: true, args: [...exports.HEADLESS_CHROMIUM_ARGS], chromiumSandbox: false });
    }
    catch (error) {
        throw createPlaywrightLaunchError(TOOL_NAME, error);
    }
    let context = null;
    try {
        const { automationOrigin, ...contextOptions } = options;
        context = await browser.newContext(contextOptions);
        await grantAutomationLocalNetworkAccess(context, automationOrigin);
        const page = await context.newPage();
        return await callback({ browser, context, page });
    }
    finally {
        if (context) {
            try {
                await context.close();
            }
            catch (closeError) {
                const message = closeError instanceof Error ? closeError.message : String(closeError);
                console.warn(`[${TOOL_NAME}] Failed to close Playwright context: ${message}`);
            }
        }
        try {
            await browser.close();
        }
        catch (closeError) {
            const message = closeError instanceof Error ? closeError.message : String(closeError);
            console.warn(`[${TOOL_NAME}] Failed to close Playwright browser: ${message}`);
        }
    }
}
async function launchPersistentChromiumContext(userDataDir, options = {}) {
    const { chromium } = await loadPlaywright();
    if (typeof chromium.launchPersistentContext !== 'function') {
        throw new Error(`[${TOOL_NAME}] Your Playwright Chromium build does not support persistent contexts.`);
    }
    try {
        const { automationOrigin, ...contextOptions } = options;
        const context = await chromium.launchPersistentContext(userDataDir, {
            ...contextOptions,
            headless: false,
            args: [...exports.INTERACTIVE_CHROMIUM_ARGS],
            chromiumSandbox: false,
        });
        await grantAutomationLocalNetworkAccess(context, automationOrigin);
        return context;
    }
    catch (error) {
        throw createPlaywrightLaunchError(TOOL_NAME, error);
    }
}
