#!/usr/bin/env php
<?php

/**
 * Script de test pour le système de sécurité et monitoring
 * Usage: php test_security.php
 */

declare(strict_types=1);

// Configuration
require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/src/Config/AppConfig.php';
require_once __DIR__ . '/src/Core/Database.php';

// Services de sécurité
require_once __DIR__ . '/src/Services/Security/AlertService.php';
require_once __DIR__ . '/src/Services/Security/SecurityMonitor.php';
require_once __DIR__ . '/src/Services/Security/PerformanceMonitor.php';
require_once __DIR__ . '/src/Services/Security/IPBlocker.php';
require_once __DIR__ . '/src/Services/Security/EmailThrottler.php';

use App\Services\Security\AlertService;
use App\Services\Security\SecurityMonitor;
use App\Services\Security\PerformanceMonitor;
use App\Services\Security\IPBlocker;
use App\Services\Security\EmailThrottler;

// Initialiser la configuration
$appConfig = AppConfig::getInstance();
$config = $appConfig->getFullConfig();

// Initialiser la base de données
Database::init($config['database']);

echo "\n========================================\n";
echo "  TEST DU SYSTÈME DE SÉCURITÉ\n";
echo "========================================\n\n";

// Test 1: Vérifier les tables
echo "1. Vérification des tables de sécurité...\n";
try {
    $db = Database::getInstance();
    
    $tables = [
        'sec_alerts',
        'sec_performance_metrics',
        'sec_failed_login_attempts',
        'sec_blocked_ips'
    ];
    
    foreach ($tables as $table) {
        $stmt = $db->query("SELECT COUNT(*) as count FROM $table");
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        echo "   ✓ Table $table : {$result['count']} enregistrements\n";
    }
    echo "   [OK] Toutes les tables existent\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n";
    echo "   Assurez-vous d'avoir exécuté le script SQL de création des tables.\n";
    exit(1);
}

// Test 2: Test du monitoring de performance
echo "2. Test du monitoring de performance...\n";
try {
    // Simuler une requête
    PerformanceMonitor::startRequest();
    
    // Simuler une requête DB
    PerformanceMonitor::startDbQuery("SELECT * FROM users WHERE id = 1");
    usleep(50000); // 50ms
    PerformanceMonitor::endDbQuery();
    
    // Terminer la requête
    PerformanceMonitor::endRequest('/api/test', 'GET', 200);
    
    echo "   ✓ Monitoring de performance fonctionnel\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Test 3: Test de détection SQL Injection
echo "3. Test de détection d'injection SQL...\n";
$testQueries = [
    "normal_query" => true,
    "'; DROP TABLE users; --" => false,
    "1' OR '1'='1" => false,
    "admin' UNION SELECT * FROM users--" => false
];

foreach ($testQueries as $query => $shouldPass) {
    $result = SecurityMonitor::checkSQLInjection($query);
    $status = ($result === $shouldPass) ? '✓' : '✗';
    $expected = $shouldPass ? 'autorisé' : 'bloqué';
    echo "   $status '$query' : $expected\n";
}
echo "\n";

// Test 4: Test du blocage d'IP
echo "4. Test du système de blocage d'IP...\n";
try {
    $testIP = '192.168.1.99';
    
    // Vérifier que l'IP n'est pas bloquée
    if (!IPBlocker::isBlocked($testIP)) {
        echo "   ✓ IP $testIP non bloquée initialement\n";
    }
    
    // Bloquer l'IP temporairement (10 secondes)
    IPBlocker::block($testIP, 10, 'Test temporaire');
    
    // Vérifier qu'elle est bloquée
    if (IPBlocker::isBlocked($testIP)) {
        echo "   ✓ IP $testIP bloquée avec succès\n";
    }
    
    // Débloquer l'IP
    IPBlocker::unblock($testIP);
    
    // Vérifier qu'elle est débloquée
    if (!IPBlocker::isBlocked($testIP)) {
        echo "   ✓ IP $testIP débloquée avec succès\n";
    }
    
    echo "   [OK] Système de blocage IP fonctionnel\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Test 5: Test des alertes
echo "5. Test du système d'alertes...\n";
try {
    // Créer une alerte de test
    AlertService::trigger('TEST', [
        'message' => 'Ceci est une alerte de test',
        'test_script' => true
    ], 'INFO');
    
    echo "   ✓ Alerte créée avec succès\n";
    
    // Récupérer les alertes actives
    $alerts = AlertService::getActiveAlerts(1);
    if (!empty($alerts)) {
        echo "   ✓ " . count($alerts) . " alerte(s) active(s) trouvée(s)\n";
    }
    
    echo "   [OK] Système d'alertes fonctionnel\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Test 6: Test de brute force
echo "6. Simulation d'attaque brute force...\n";
try {
    $attackerIP = '10.0.0.1';
    
    // Simuler plusieurs tentatives échouées
    for ($i = 1; $i <= 6; $i++) {
        SecurityMonitor::recordFailedLogin(
            $attackerIP, 
            'user' . $i, 
            'invalid_password',
            'Mozilla/5.0 Test'
        );
        echo "   - Tentative $i enregistrée\n";
    }
    
    // Vérifier la détection
    $canLogin = SecurityMonitor::checkBruteForce($attackerIP, 'testuser');
    
    if (!$canLogin) {
        echo "   ✓ Attaque brute force détectée et bloquée\n";
    } else {
        echo "   ✗ L'attaque aurait dû être détectée\n";
    }
    
    // Nettoyer
    $db->exec("DELETE FROM sec_failed_login_attempts WHERE ip_address = '$attackerIP'");
    IPBlocker::unblock($attackerIP);
    
    echo "   [OK] Détection brute force fonctionnelle\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Test 7: Test du throttling email
echo "7. Test du throttling d'emails...\n";
try {
    $throttler = new EmailThrottler();
    
    // Premier email devrait passer
    if ($throttler->canSend('TEST_TYPE', 60)) {
        echo "   ✓ Premier email autorisé\n";
        $throttler->recordSent('TEST_TYPE');
    }
    
    // Deuxième email immédiat devrait être bloqué
    if (!$throttler->canSend('TEST_TYPE', 60)) {
        echo "   ✓ Deuxième email bloqué (throttling)\n";
    }
    
    // Obtenir les stats
    $stats = $throttler->getStats();
    echo "   ✓ Stats throttling : {$stats['hourly']['sent']} emails/heure\n";
    
    echo "   [OK] Throttling email fonctionnel\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Test 8: Statistiques globales
echo "8. Récupération des statistiques...\n";
try {
    // Stats de sécurité
    $securityStats = SecurityMonitor::getSecurityStats();
    echo "   ✓ Tentatives de login échouées (24h) : " . 
         ($securityStats['failed_logins']['total_attempts'] ?? 0) . "\n";
    
    // Stats de performance
    $perfStats = PerformanceMonitor::getStats(null, 24);
    echo "   ✓ Requêtes totales (24h) : " . 
         ($perfStats['global']['total_requests'] ?? 0) . "\n";
    
    // Stats de blocage IP
    $ipStats = IPBlocker::getStats();
    echo "   ✓ IPs bloquées actives : " . 
         (($ipStats['totals']['temporary'] ?? 0) + ($ipStats['totals']['permanent'] ?? 0)) . "\n";
    
    echo "   [OK] Statistiques disponibles\n\n";
} catch (Exception $e) {
    echo "   ✗ Erreur : " . $e->getMessage() . "\n\n";
}

// Résumé
echo "========================================\n";
echo "  RÉSUMÉ DES TESTS\n";
echo "========================================\n\n";
echo "✓ Tables de sécurité créées\n";
echo "✓ Monitoring de performance actif\n";
echo "✓ Détection SQL injection fonctionnelle\n";
echo "✓ Blocage d'IP opérationnel\n";
echo "✓ Système d'alertes configuré\n";
echo "✓ Détection brute force active\n";
echo "✓ Throttling email en place\n";
echo "✓ Statistiques disponibles\n\n";

echo "🔒 Le système de sécurité est opérationnel !\n\n";

echo "PROCHAINES ÉTAPES :\n";
echo "1. Configurer l'email dans AppConfig pour recevoir les alertes\n";
echo "2. Personnaliser les seuils dans les constantes des services\n";
echo "3. Tester avec de vraies requêtes API\n";
echo "4. Surveiller les logs et ajuster les règles\n\n";