#!/usr/bin/env node
/**
 * Test-Script zum Prüfen, ob WebSocket über Apache erreichbar ist
 * 
 * Verwendung:
 *   node scripts/testWebSocketApache.js
 *   node scripts/testWebSocketApache.js https://tt-tagebuch.de
 */

import https from 'https';
import http from 'http';

const url = process.argv[2] || 'https://tt-tagebuch.de';
const isHttps = url.startsWith('https://');
const client = isHttps ? https : http;

console.log(`🔌 Teste Socket.IO-Server über ${isHttps ? 'Apache (HTTPS)' : 'HTTP'} auf ${url}...\n`);

// Test 1: HTTP-Polling (Socket.IO Handshake)
console.log('1️⃣ Teste HTTP-Polling (Socket.IO Handshake)...');
const pollingUrl = `${url}/socket.io/?EIO=4&transport=polling`;

const pollingReq = client.get(pollingUrl, {
    rejectUnauthorized: false // Für selbst-signierte Zertifikate
}, (res) => {
    let data = '';
    
    res.on('data', (chunk) => {
        data += chunk;
    });
    
    res.on('end', () => {
        if (res.statusCode === 200) {
            console.log('   ✅ HTTP-Polling erfolgreich!');
            console.log(`   Status: ${res.statusCode}`);
            console.log(`   Response: ${data.substring(0, 200)}...`);
            
            // Versuche Session-ID zu extrahieren
            try {
                const jsonMatch = data.match(/\{.*\}/);
                if (jsonMatch) {
                    const json = JSON.parse(jsonMatch[0]);
                    if (json.sid) {
                        console.log(`   Session ID: ${json.sid}`);
                        
                        // Test 2: WebSocket-Upgrade
                        console.log('\n2️⃣ Teste WebSocket-Upgrade...');
                        testWebSocketUpgrade(url, json.sid, isHttps);
                    }
                }
            } catch (e) {
                console.log('   ⚠️  Konnte Session-ID nicht extrahieren');
                console.log('\n2️⃣ Teste WebSocket-Upgrade ohne Session-ID...');
                testWebSocketUpgrade(url, null, isHttps);
            }
        } else {
            console.error(`   ❌ HTTP-Polling fehlgeschlagen: Status ${res.statusCode}`);
            process.exit(1);
        }
    });
});

pollingReq.on('error', (error) => {
    console.error('   ❌ HTTP-Polling Fehler:');
    console.error(`   ${error.message}`);
    if (error.code === 'ECONNREFUSED') {
        console.error('   → Server läuft möglicherweise nicht oder ist nicht erreichbar');
    }
    process.exit(1);
});

pollingReq.setTimeout(10000, () => {
    pollingReq.destroy();
    console.error('   ❌ Timeout: Keine Antwort innerhalb von 10 Sekunden');
    process.exit(1);
});

function testWebSocketUpgrade(baseUrl, sessionId, useHttps) {
    // WebSocket-Upgrade-Request
    // Sec-WebSocket-Key muss 16 Bytes (128 Bits) sein, base64-encoded
    const wsKey = Buffer.allocUnsafe(16);
    for (let i = 0; i < 16; i++) {
        wsKey[i] = Math.floor(Math.random() * 256);
    }
    const wsKeyBase64 = wsKey.toString('base64');
    const path = sessionId 
        ? `/socket.io/?EIO=4&transport=websocket&sid=${sessionId}`
        : `/socket.io/?EIO=4&transport=websocket`;
    
    const urlObj = new URL(baseUrl);
    const options = {
        hostname: urlObj.hostname,
        port: urlObj.port || (useHttps ? 443 : 80),
        path: path,
        method: 'GET',
        headers: {
            'Upgrade': 'websocket',
            'Connection': 'Upgrade',
            'Sec-WebSocket-Key': wsKeyBase64,
            'Sec-WebSocket-Version': '13',
            'Sec-WebSocket-Protocol': 'chat, superchat',
            'Origin': baseUrl
        },
        rejectUnauthorized: false // Für selbst-signierte Zertifikate
    };
    
    const client = useHttps ? https : http;
    const wsReq = client.request(options, (res) => {
        console.log(`   Status: ${res.statusCode}`);
        console.log(`   Upgrade Header: ${res.headers.upgrade || 'nicht gesetzt'}`);
        console.log(`   Connection Header: ${res.headers.connection || 'nicht gesetzt'}`);
        
        if (res.statusCode === 101) {
            console.log('   ✅ WebSocket-Upgrade erfolgreich!');
            console.log(`   Status: ${res.statusCode} (Switching Protocols)`);
            console.log('\n✅ Socket.IO-Server ist über Apache erreichbar und unterstützt WebSockets!');
            process.exit(0);
        } else if (res.statusCode === 400) {
            console.log(`   ⚠️  WebSocket-Upgrade: Status ${res.statusCode} (Bad Request)`);
            console.log(`   → Apache leitet weiter, aber Backend akzeptiert den Request nicht`);
            console.log(`   → Möglicherweise fehlen Header oder die Session-ID ist ungültig`);
        } else {
            console.log(`   ⚠️  WebSocket-Upgrade: Status ${res.statusCode} (erwartet: 101)`);
            console.log(`   → Server antwortet, aber Upgrade nicht erfolgreich`);
        }
        
        // Lese Response-Body für weitere Informationen
        let body = '';
        res.on('data', (chunk) => {
            body += chunk;
        });
        res.on('end', () => {
            if (body) {
                console.log(`   Response Body: ${body.substring(0, 200)}`);
            }
            console.log('\n⚠️  HTTP-Polling funktioniert, aber WebSocket-Upgrade schlägt fehl.');
            console.log('   → Das könnte ein Problem mit der Apache-Konfiguration sein.');
            process.exit(0);
        });
    });
    
    wsReq.on('error', (error) => {
        console.error('   ❌ WebSocket-Upgrade Fehler:');
        console.error(`   ${error.message}`);
        if (error.code === 'ECONNREFUSED') {
            console.error('   → Verbindung wurde abgelehnt');
        } else if (error.code === 'ENOTFOUND') {
            console.error('   → Hostname nicht gefunden');
        }
        console.log('\n⚠️  HTTP-Polling funktioniert, aber WebSocket-Upgrade schlägt fehl.');
        console.log('   → Das könnte ein Problem mit der Apache-Konfiguration sein.');
        process.exit(0);
    });
    
    wsReq.setTimeout(10000, () => {
        wsReq.destroy();
        console.error('   ❌ Timeout: Keine Antwort innerhalb von 10 Sekunden');
        process.exit(1);
    });
    
    wsReq.end();
}

