import { createModuleLogger } from '../../logger.js';
const logger = createModuleLogger('XCTestParserStrategy');
/**
 * Parser strategy for XCTest framework output
 */
export class XCTestParserStrategy {
    canParse(output) {
        // XCTest specific patterns
        return output.includes('Test Suite') ||
            output.includes('Test Case') ||
            output.includes('** TEST SUCCEEDED **') ||
            output.includes('** TEST FAILED **') ||
            output.includes('XCTest') ||
            output.includes('XCTAssert') ||
            output.includes('XCTFail') ||
            // Also check for the summary format
            /Executed \d+ tests?/.test(output);
    }
    parse(output) {
        let passed = 0;
        let failed = 0;
        const failingTests = [];
        // Log what we're looking for
        const hasAllTests = output.includes("Test Suite 'All tests'");
        const hasSelectedTests = output.includes("Test Suite 'Selected tests'");
        const allTestsIndex = output.indexOf("Test Suite 'All tests'");
        logger.info({
            hasAllTests,
            hasSelectedTests,
            allTestsIndex,
            sampleOutput: allTestsIndex >= 0 ? output.substring(allTestsIndex, Math.min(allTestsIndex + 300, output.length)) : 'No Test Suite found'
        }, 'XCTestParser: Looking for test summaries');
        // Try to find the test summary (most reliable)
        // When both XCTest and Swift Testing run, there can be multiple "All tests" summaries:
        // - One with 0 tests (Swift Testing phase when no Swift Testing tests in XCTest target)
        // - One with actual XCTest results
        // The reliable one is either:
        // 1. The one that comes right after .xctest summary
        // 2. The one with non-zero test count
        const topLevelPattern = /Test Suite '(?:All tests|Selected tests)' (?:passed|failed)[^\n]*\n\s*Executed (\d+) tests?, with (\d+) failures?/g;
        const allMatches = [...output.matchAll(topLevelPattern)];
        let topLevelSummary = null;
        if (allMatches.length === 1) {
            // Only one match, use it
            topLevelSummary = allMatches[0];
            console.log('[XCTestParser] Found single "All tests" summary');
        }
        else if (allMatches.length > 1) {
            console.log('[XCTestParser] Found', allMatches.length, '"All tests" summaries, selecting best one');
            // Multiple matches - prefer the one with non-zero tests
            // (Swift Testing phase shows 0 tests when there are no Swift Testing tests)
            const nonZeroMatches = allMatches.filter(m => parseInt(m[1], 10) > 0);
            if (nonZeroMatches.length > 0) {
                // Use the match with the most tests
                topLevelSummary = nonZeroMatches.reduce((best, current) => {
                    const currentTests = parseInt(current[1], 10);
                    const bestTests = parseInt(best[1], 10);
                    return currentTests > bestTests ? current : best;
                });
                console.log('[XCTestParser] Selected "All tests" with', topLevelSummary[1], 'tests');
            }
            else {
                // All have 0 tests, use the last one
                topLevelSummary = allMatches[allMatches.length - 1];
                console.log('[XCTestParser] All summaries have 0 tests, using last one');
            }
        }
        console.log('[XCTestParser] Using:', topLevelSummary ? `${topLevelSummary[1]} tests, ${topLevelSummary[2]} failures` : 'NOT FOUND');
        // Log what we found
        logger.debug({
            topLevelSummaryFound: !!topLevelSummary,
            match: topLevelSummary ? topLevelSummary[0] : null
        }, 'XCTestParser: Top level summary search');
        if (topLevelSummary) {
            // Use the top-level summary
            const tests = parseInt(topLevelSummary[1], 10);
            const failures = parseInt(topLevelSummary[2], 10);
            passed = tests - failures;
            failed = failures;
            console.log('[XCTestParser] Using top-level summary:', { passed, failed });
            logger.info({ totalTests: tests, passed, failed, matchedText: topLevelSummary[0] }, 'XCTestParser: Parsed top-level summary');
        }
        else {
            console.log('[XCTestParser] No top-level summary, checking individual suites...');
            // Try to find individual test suite summaries (e.g., "MyAppTests", "MyAppUITests")
            // Also make this regex more flexible with \s* to handle indentation
            const testSuitePattern = /Test Suite '([^']+)' (?:passed|failed)[^\n]*\n\s*Executed (\d+) tests?, with (\d+) failures?/g;
            const suiteMatches = [...output.matchAll(testSuitePattern)];
            if (suiteMatches.length > 0) {
                // Aggregate results from multiple test suites
                for (const match of suiteMatches) {
                    const suiteName = match[1];
                    // Skip the top-level summaries we already checked
                    if (suiteName === 'All tests' || suiteName === 'Selected tests') {
                        continue;
                    }
                    const tests = parseInt(match[2], 10);
                    const failures = parseInt(match[3], 10);
                    passed += tests - failures;
                    failed += failures;
                    logger.debug({ suiteName, tests, failures }, 'Parsed individual test suite');
                }
                logger.debug({ totalPassed: passed, totalFailed: failed }, 'Aggregated test suite results');
            }
            else {
                // Fallback: Count individual test passes/failures
                const passedMatches = output.match(/Test Case .* passed/g);
                const failedMatches = output.match(/Test Case .* failed/g);
                passed = passedMatches ? passedMatches.length : 0;
                failed = failedMatches ? failedMatches.length : 0;
                logger.debug({ passed, failed }, 'Parsed XCTest by counting individual tests');
            }
        }
        // Extract failing test names
        // Format: Test Case '-[TestClass testMethod]' failed
        const bracketFormatMatches = output.matchAll(/Test Case '\-\[([^\]]+)\]' failed/g);
        for (const match of bracketFormatMatches) {
            let testName = match[1];
            // Extract just the method name from "TestClass testMethod"
            const parts = testName.split(' ');
            if (parts.length >= 2) {
                failingTests.push(parts[1]);
            }
        }
        // Also try the format: Test Case 'TestTarget.TestClass/testMethod' failed
        const modernFormatMatches = output.matchAll(/Test Case '([^']+)' failed/g);
        for (const match of modernFormatMatches) {
            const testName = match[1];
            // Don't add duplicates
            if (!failingTests.includes(testName) && !testName.startsWith('-[')) {
                failingTests.push(testName);
            }
        }
        const result = {
            success: failed === 0 && (passed > 0 || output.includes('** TEST SUCCEEDED **')),
            passed,
            failed,
            failingTests: failingTests.length > 0 ? failingTests : undefined
        };
        logger.info({ result }, 'XCTestParser: Final parsing result');
        return result;
    }
}
//# sourceMappingURL=XCTestParserStrategy.js.map