/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import crypto from 'crypto';
import { stripAnsiEscapes } from '@isomorphic/stringUtils';
export function createCustomMessageHandler(testInfo, context) {
    let backend;
    const config = { capabilities: ['testing'] };
    let tools;
    return async (data) => {
        if (!tools)
            ({ tools } = require('playwright-core/lib/coreBundle'));
        const toolList = tools.filteredTools(config);
        if (data.initialize) {
            if (backend)
                throw new Error('MCP backend is already initialized');
            backend = new tools.BrowserBackend(config, context, toolList);
            await backend.initialize(data.initialize.clientInfo);
            const pausedMessage = await generatePausedMessage(tools, testInfo, context);
            return { initialize: { pausedMessage } };
        }
        if (data.callTool) {
            if (!backend)
                throw new Error('MCP backend is not initialized');
            return { callTool: await backend.callTool(data.callTool.name, data.callTool.arguments) };
        }
        if (data.close) {
            await backend?.dispose();
            backend = undefined;
            return { close: {} };
        }
        throw new Error('Unknown MCP request');
    };
}
async function generatePausedMessage(tools, testInfo, context) {
    const lines = [];
    if (testInfo.errors.length) {
        lines.push(`### Paused on error:`);
        for (const error of testInfo.errors)
            lines.push(stripAnsiEscapes(error.message || ''));
    }
    else {
        lines.push(`### Paused at end of test. ready for interaction`);
    }
    for (let i = 0; i < context.pages().length; i++) {
        const page = context.pages()[i];
        const stateSuffix = context.pages().length > 1 ? (i + 1) + ' of ' + (context.pages().length) : 'state';
        lines.push('', `### Page ${stateSuffix}`, `- Page URL: ${page.url()}`, `- Page Title: ${await page.title()}`.trim());
        // Only print console errors when pausing on error, not when everything works as expected.
        let console = testInfo.errors.length ? await tools.Tab.collectConsoleMessages(page) : [];
        console = console.filter(msg => msg.type === 'error');
        if (console.length) {
            lines.push('- Console Messages:');
            for (const message of console)
                lines.push(`  - ${message.toString()}`);
        }
        lines.push(`- Page Snapshot:`, '```yaml', await page.ariaSnapshot({ mode: 'ai' }), '```');
    }
    lines.push('');
    if (testInfo.errors.length)
        lines.push(`### Task`, `Try recovering from the error prior to continuing`);
    return lines.join('\n');
}
export async function runDaemonForContext(testInfo, context) {
    if (testInfo._configInternal.configCLIOverrides.debug !== 'cli')
        return false;
    const sessionName = `tw-${crypto.randomBytes(3).toString('hex')}`;
    await context.browser().bind(sessionName, { workspaceDir: testInfo.project.testDir });
    /* eslint-disable-next-line no-console */
    console.log([
        `### The test is currently paused at the start`,
        ``,
        `### Debugging Instructions`,
        `- Run "playwright-cli attach ${sessionName}" to attach to this test`,
    ].join('\n'));
    await context.debugger.requestPause();
    return true;
}
//# sourceMappingURL=browserBackend.js.map