// tools/browser-validate-handler.ts — SPEC-308: Browser validation tool handler
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { specStore } from '../storage/index.js';
import { hashProjectPath } from '../storage/base-store.js';
import { extractUIAssertions, generatePlaywrightTest, checkPlaywrightAvailable, } from '../engine/browser-validator.js';
import { formatSuccess, formatWarning, toolResult } from './response-helpers.js';
const execFileAsync = promisify(execFile);
/** Write the generated test file and return the path. */
async function saveTestFile(projectPath, specId, testContent) {
    const e2eDir = path.join(projectPath, 'tests', 'e2e');
    await fs.mkdir(e2eDir, { recursive: true });
    const filePath = path.join(e2eDir, `spec-${specId}.spec.ts`);
    await fs.writeFile(filePath, testContent, 'utf-8');
    return filePath;
}
/** Parse playwright test output into pass/fail/skip counts. */
function parsePlaywrightOutput(output) {
    const passMatch = /(\d+)\s+passed/i.exec(output);
    const failMatch = /(\d+)\s+failed/i.exec(output);
    const skipMatch = /(\d+)\s+skipped/i.exec(output);
    return {
        passed: passMatch?.[1] ? parseInt(passMatch[1], 10) : 0,
        failed: failMatch?.[1] ? parseInt(failMatch[1], 10) : 0,
        skipped: skipMatch?.[1] ? parseInt(skipMatch[1], 10) : 0,
        output,
    };
}
/** Run playwright tests against a saved test file. */
async function runPlaywrightTests(testFilePath) {
    try {
        const { stdout, stderr } = await execFileAsync('npx', ['playwright', 'test', testFilePath, '--reporter=line'], { timeout: 60_000 });
        return parsePlaywrightOutput(stdout + stderr);
    }
    catch (err) {
        const output = err instanceof Error ? err.message : String(err);
        return parsePlaywrightOutput(output);
    }
}
export async function handleValidateBrowser(args) {
    const { projectPath, specId, baseUrl } = args;
    // Load spec
    const projectId = hashProjectPath(projectPath);
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return toolResult(formatWarning('Spec not found', `Spec **${specId}** not found in project at ${projectPath}. ` +
            'Run `list_specs` to see available specs.'), undefined, true);
    }
    // Read spec markdown file to extract acceptance criteria
    let specContent;
    try {
        specContent = await fs.readFile(spec.specPath, 'utf-8');
    }
    catch {
        // Fall back to spec title if file not readable
        specContent = `- [ ] ${spec.title}`;
    }
    const assertions = extractUIAssertions(specContent);
    const playwrightVersion = await checkPlaywrightAvailable();
    const testContent = generatePlaywrightTest(assertions, specId, baseUrl);
    const result = {
        specId,
        baseUrl,
        playwrightVersion,
        assertions,
    };
    if (playwrightVersion) {
        // Playwright is available — save temp file and run
        const testFilePath = await saveTestFile(projectPath, specId, testContent);
        const testResults = await runPlaywrightTests(testFilePath);
        result.testFilePath = testFilePath;
        result.testResults = testResults;
        const summary = testResults.failed === 0
            ? `All ${String(testResults.passed)} assertion(s) passed.`
            : `${String(testResults.passed)} passed, ${String(testResults.failed)} failed, ${String(testResults.skipped)} skipped.`;
        const lines = [
            `Spec: **${specId}**`,
            `Base URL: ${baseUrl}`,
            `Playwright: ${playwrightVersion}`,
            `Assertions extracted: ${String(assertions.length)}`,
            ``,
            `**Test Results:** ${summary}`,
            ``,
            `Test file: \`${testFilePath}\``,
        ];
        return toolResult(formatSuccess('Browser Validation Complete', lines.join('\n')), result);
    }
    // Playwright not available — save test file and return instructions
    const testFilePath = await saveTestFile(projectPath, specId, testContent);
    result.testFilePath = testFilePath;
    result.instructions = [
        'Install Playwright: `npm install -D @playwright/test && npx playwright install`',
        `Run tests: \`npx playwright test ${testFilePath}\``,
        'Or run in UI mode: `npx playwright test --ui`',
    ].join('\n');
    const lines = [
        `Spec: **${specId}**`,
        `Base URL: ${baseUrl}`,
        `Playwright: not found`,
        `Assertions extracted: ${String(assertions.length)}`,
        ``,
        `**Test file saved:** \`${testFilePath}\``,
        ``,
        `**To run the tests:**`,
        result.instructions,
    ];
    return toolResult(formatSuccess('Browser Test File Generated', lines.join('\n')), result);
}
//# sourceMappingURL=browser-validate-handler.js.map