/**
 * Socket.IO Initialization Timing Test
 *
 * Verifies that Socket.IO does NOT block DOMContentLoaded.
 * This test was added after a fix for CI test timeouts where Socket.IO
 * initialization was blocking the 'domcontentloaded' event.
 *
 * Background: Socket.IO was causing 30-second navigation timeouts in CI because
 * it initialized immediately on script load, blocking DOMContentLoaded detection.
 * Fix: Defer initialization until after DOMContentLoaded fires.
 *
 * What this test verifies:
 * 1. Navigation to various pages completes within the timeout (no blocking)
 * 2. Navigation time is reasonable (<5 seconds per page)
 * 3. Where socket console messages are available, verify conditional initialization
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('./auth_helper');
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');

// Short timeout - if Socket.IO blocks DOMContentLoaded, this will fail
// The original bug caused 30+ second delays; 10 seconds gives ample margin
const NAVIGATION_TIMEOUT = 10000;

// Warning threshold - navigation should be much faster than this
const NAVIGATION_WARNING_THRESHOLD = 5000;

// Test pages - mix of pages where socket is/isn't needed
const TEST_PAGES = [
    { path: '/', name: 'Home', expectSocket: false },
    { path: '/settings/', name: 'Settings', expectSocket: false },
    { path: '/metrics/', name: 'Metrics', expectSocket: false },
    { path: '/news/', name: 'News', expectSocket: false },
    { path: '/research', name: 'Research', expectSocket: true },
];

/**
 * Simple delay function
 */
function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function runTest() {
    const baseUrl = process.env.TEST_BASE_URL || 'http://127.0.0.1:5000';
    let passed = 0;
    let failed = 0;
    let warnings = 0;

    console.log('='.repeat(60));
    console.log('Socket.IO Initialization Timing Test');
    console.log('='.repeat(60));
    console.log(`Base URL: ${baseUrl}`);
    console.log(`Navigation timeout: ${NAVIGATION_TIMEOUT}ms`);
    console.log(`Warning threshold: ${NAVIGATION_WARNING_THRESHOLD}ms`);
    console.log(`Environment: ${process.env.CI ? 'CI' : 'Local'}`);
    console.log('');

    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
    const page = await browser.newPage();

    try {
        // Authenticate
        console.log('Authenticating...');
        const auth = new AuthHelper(page, baseUrl);
        const testUser = process.env.CI
            ? { username: 'test_admin', password: 'testpass123' }
            : { username: 'testuser', password: 'T3st!Secure#2024$LDR' };
        await auth.ensureAuthenticated(testUser.username, testUser.password);
        console.log('Authentication successful\n');

        for (const testPage of TEST_PAGES) {
            const url = `${baseUrl}${testPage.path}`;
            console.log(`Testing: ${testPage.name} (${testPage.path})`);

            // Collect console messages for this page only
            const consoleMessages = [];
            const pageErrors = [];
            const consoleHandler = msg => consoleMessages.push(msg.text());
            const errorHandler = err => pageErrors.push(err.message);

            page.on('console', consoleHandler);
            page.on('pageerror', errorHandler);

            try {
                // Primary test: navigation completes within timeout
                // This is the main thing we're testing - if Socket.IO blocks
                // DOMContentLoaded, this navigation will timeout
                const startTime = Date.now();
                await page.goto(url, {
                    waitUntil: 'domcontentloaded',
                    timeout: NAVIGATION_TIMEOUT
                });
                const navTime = Date.now() - startTime;

                // Test passed if navigation completed
                console.log(`  \u2713 Navigation completed: ${navTime}ms`);
                passed++;

                // Warn if navigation was slow (but still passed)
                if (navTime > NAVIGATION_WARNING_THRESHOLD) {
                    console.log(`  \u26a0 WARNING: Navigation took ${navTime}ms (threshold: ${NAVIGATION_WARNING_THRESHOLD}ms)`);
                    warnings++;
                }

                // Wait a bit for any async socket initialization
                await delay(300);

                // Secondary check: look for socket-related console messages
                // This helps verify the conditional initialization is working
                const socketMessages = consoleMessages.filter(m =>
                    m.toLowerCase().includes('socket')
                );

                if (socketMessages.length > 0) {
                    // Found socket messages - check for expected behavior
                    const notNeededMsg = socketMessages.find(m =>
                        m.includes('not needed on this page')
                    );
                    const initializedMsg = socketMessages.find(m =>
                        m.includes('Socket.IO initialized')
                    );

                    if (!testPage.expectSocket && notNeededMsg) {
                        console.log(`  \u2713 Socket correctly skipped on ${testPage.name}`);
                    } else if (testPage.expectSocket && initializedMsg) {
                        console.log(`  \u2713 Socket correctly initialized on ${testPage.name}`);
                    } else if (testPage.expectSocket && !initializedMsg) {
                        // Research page didn't show initialization message
                        // This might be due to SafeLogger not being available yet
                        console.log(`  \u2139 Socket initialization message not captured`);
                    }
                }

                // Note any page errors (informational only)
                if (pageErrors.length > 0) {
                    console.log(`  \u2139 Page errors: ${pageErrors.join(', ').substring(0, 100)}`);
                }

            } catch (error) {
                console.log(`  \u2717 Navigation FAILED: ${error.message}`);
                if (error.message.includes('timeout')) {
                    console.log('    *** Socket.IO may be blocking DOMContentLoaded ***');
                }
                failed++;
            } finally {
                page.off('console', consoleHandler);
                page.off('pageerror', errorHandler);
            }

            console.log('');
        }

    } finally {
        await browser.close();
    }

    console.log('='.repeat(60));
    console.log(`Results: ${passed} passed, ${failed} failed, ${warnings} warnings`);
    console.log('');
    if (failed === 0) {
        console.log('SUCCESS: DOMContentLoaded is not blocked by Socket.IO');
    } else {
        console.log('FAILURE: Some pages failed to load within timeout');
        console.log('This may indicate Socket.IO is blocking DOMContentLoaded');
    }
    console.log('='.repeat(60));

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

runTest().catch(err => {
    console.error('Test error:', err);
    process.exit(1);
});
