/**
 * UI Test Suite Runner
 *
 * Runs all UI tests in sequence and provides a summary report.
 * This script executes each test individually and tracks pass/fail status.
 *
 * Prerequisites: Web server running on http://127.0.0.1:5000
 *
 * Usage: node tests/ui_tests/run_all_tests.js
 */

const { spawn } = require('child_process');
const path = require('path');

const tests = [
    {
        name: 'Authentication Flow Test',
        file: 'test_auth_flow.js',
        description: 'Tests registration, login, and logout functionality'
    },
    {
        name: 'All Pages Browser Test',
        file: 'test_pages_browser.js',
        description: 'Tests all main pages for basic functionality'
    },
    {
        name: 'Metrics Charts Test',
        file: 'test_metrics_charts.js',
        description: 'Tests Chart.js rendering for token and search charts'
    },
    {
        name: 'Research Results Test',
        file: 'test_research_results.js',
        description: 'Tests error handling for non-existent research and history page structure'
    },
    {
        name: 'Settings Page Test',
        file: 'test_settings_page.js',
        description: 'Tests settings page loading and API integration'
    },
    {
        name: 'Settings Error Detection Test',
        file: 'test_settings_errors.js',
        description: 'Tests error handling when changing settings'
    },
    {
        name: 'Settings Save Test',
        file: 'test_settings_save.js',
        description: 'Tests settings save workflow and validation'
    },
    {
        name: 'Star Reviews Test',
        file: 'test_star_reviews.js',
        description: 'Tests star reviews analytics page and visualizations'
    },
    {
        name: 'Rate Limiting Functionality Test',
        file: 'test_rate_limiting_settings.js',
        description: 'Tests rate limiting works on auth endpoints and static files are exempt'
    }
];

async function runTest(test) {
    return new Promise((resolve) => {
        const startTime = Date.now();
        console.log(`\n📋 Running: ${test.name}`);
        console.log(`📄 Description: ${test.description}`);
        console.log(`🔧 File: ${test.file}`);
        console.log(`⏰ Started at: ${new Date().toISOString()}`);
        console.log('─'.repeat(60));

        const testProcess = spawn('node', [test.file], {
            cwd: path.join(__dirname),
            stdio: 'inherit',
            env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=4096' }
        });

        console.log(`🆔 Process PID: ${testProcess.pid}`);

        // Add timeout for individual tests (60 seconds)
        const timeout = setTimeout(() => {
            const elapsed = Math.round((Date.now() - startTime) / 1000);
            console.log(`\n⏱️ Test timeout: ${test.name} exceeded 60 seconds (${elapsed}s elapsed)`);
            console.log(`🔪 Sending SIGTERM to PID ${testProcess.pid}...`);
            testProcess.kill('SIGTERM');
            setTimeout(() => {
                if (!testProcess.killed) {
                    console.log(`🔫 Process still alive, sending SIGKILL to PID ${testProcess.pid}...`);
                    testProcess.kill('SIGKILL');
                }
            }, 5000);
        }, 60000);

        testProcess.on('close', (code) => {
            clearTimeout(timeout);
            const elapsed = Math.round((Date.now() - startTime) / 1000);
            const success = code === 0;
            console.log('─'.repeat(60));
            console.log(`${success ? '✅' : '❌'} ${test.name}: ${success ? 'PASSED' : 'FAILED'} (${elapsed}s)`);
            if (code !== 0 && code !== null) {
                console.log(`   Exit code: ${code}`);
            }
            console.log('');
            resolve({
                name: test.name,
                success,
                code,
                duration: elapsed
            });
        });

        testProcess.on('error', (error) => {
            clearTimeout(timeout);
            const elapsed = Math.round((Date.now() - startTime) / 1000);
            console.log('─'.repeat(60));
            console.log(`❌ ${test.name}: ERROR - ${error.message} (${elapsed}s)`);
            console.log(`   Error details: ${JSON.stringify(error)}`);
            console.log('');
            resolve({
                name: test.name,
                success: false,
                error: error.message,
                duration: elapsed
            });
        });
    });
}

async function runAllTests() {
    console.log('🚀 Starting UI Test Suite');
    console.log('=' .repeat(60));
    console.log('📍 Make sure the web server is running on http://127.0.0.1:5000');
    console.log('🕐 Starting tests...\n');

    const results = [];

    for (const test of tests) {
        const result = await runTest(test);
        results.push(result);
    }

    // Print summary
    console.log('\n' + '=' .repeat(60));
    console.log('📊 TEST SUMMARY');
    console.log('=' .repeat(60));

    const passed = results.filter(r => r.success).length;
    const failed = results.filter(r => !r.success).length;
    const totalDuration = results.reduce((sum, r) => sum + (r.duration || 0), 0);

    results.forEach(result => {
        const status = result.success ? '✅ PASS' : '❌ FAIL';
        const duration = result.duration ? ` (${result.duration}s)` : '';
        console.log(`${status} ${result.name}${duration}`);
        if (result.error) {
            console.log(`       Error: ${result.error}`);
        }
    });

    console.log('─'.repeat(60));
    console.log(`📈 Total Tests: ${results.length}`);
    console.log(`✅ Passed: ${passed}`);
    console.log(`❌ Failed: ${failed}`);
    console.log(`⏱️  Total Duration: ${totalDuration}s`);
    console.log(`📊 Success Rate: ${Math.round((passed / results.length) * 100)}%`);

    if (failed === 0) {
        console.log('\n🎉 All tests passed!');
    } else {
        console.log(`\n⚠️  ${failed} test(s) failed. Check the output above for details.`);
    }

    process.exit(failed > 0 ? 1 : 0);
}

runAllTests().catch(error => {
    console.error('💥 Test runner error:', error);
    process.exit(1);
});
