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

/**
 * Script de nettoyage des données de sécurité
 * À exécuter via cron quotidiennement
 * Exemple crontab: 0 2 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_security_data.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';

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

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

// Configuration de rétention (en jours)
$RETENTION_DAYS = [
    'performance_metrics' => 30,  // Garder 30 jours de métriques
    'failed_login_attempts' => 7, // Garder 7 jours de tentatives
    'resolved_alerts' => 90,      // Garder 90 jours d'alertes résolues
    'expired_blocks' => 0          // Débloquer immédiatement les IPs expirées
];

echo "[" . date('Y-m-d H:i:s') . "] Début du nettoyage des données de sécurité\n";

try {
    $totalDeleted = 0;
    
    // 1. Nettoyer les métriques de performance
    echo "- Nettoyage des métriques de performance (>" . $RETENTION_DAYS['performance_metrics'] . " jours)...\n";
    $stmt = $db->prepare('
        DELETE FROM sec_performance_metrics 
        WHERE created_at < DATE_SUB(NOW(), INTERVAL :days DAY)
    ');
    $stmt->execute(['days' => $RETENTION_DAYS['performance_metrics']]);
    $deleted = $stmt->rowCount();
    echo "  → $deleted lignes supprimées\n";
    $totalDeleted += $deleted;
    
    // 2. Nettoyer les tentatives de login échouées
    echo "- Nettoyage des tentatives de login (>" . $RETENTION_DAYS['failed_login_attempts'] . " jours)...\n";
    $stmt = $db->prepare('
        DELETE FROM sec_failed_login_attempts 
        WHERE attempt_time < DATE_SUB(NOW(), INTERVAL :days DAY)
    ');
    $stmt->execute(['days' => $RETENTION_DAYS['failed_login_attempts']]);
    $deleted = $stmt->rowCount();
    echo "  → $deleted lignes supprimées\n";
    $totalDeleted += $deleted;
    
    // 3. Nettoyer les alertes résolues
    echo "- Nettoyage des alertes résolues (>" . $RETENTION_DAYS['resolved_alerts'] . " jours)...\n";
    $stmt = $db->prepare('
        DELETE FROM sec_alerts 
        WHERE resolved = 1 
          AND resolved_at < DATE_SUB(NOW(), INTERVAL :days DAY)
    ');
    $stmt->execute(['days' => $RETENTION_DAYS['resolved_alerts']]);
    $deleted = $stmt->rowCount();
    echo "  → $deleted lignes supprimées\n";
    $totalDeleted += $deleted;
    
    // 4. Débloquer les IPs expirées
    echo "- Déblocage des IPs expirées...\n";
    $stmt = $db->prepare('
        UPDATE sec_blocked_ips 
        SET unblocked_at = NOW()
        WHERE blocked_until <= NOW() 
          AND unblocked_at IS NULL
          AND permanent = 0
    ');
    $stmt->execute();
    $unblocked = $stmt->rowCount();
    echo "  → $unblocked IPs débloquées\n";
    
    // 5. Supprimer les anciennes IPs débloquées (optionnel, garder 180 jours d'historique)
    echo "- Suppression des anciennes IPs débloquées (>180 jours)...\n";
    $stmt = $db->prepare('
        DELETE FROM sec_blocked_ips 
        WHERE unblocked_at IS NOT NULL 
          AND unblocked_at < DATE_SUB(NOW(), INTERVAL 180 DAY)
    ');
    $stmt->execute();
    $deleted = $stmt->rowCount();
    echo "  → $deleted lignes supprimées\n";
    $totalDeleted += $deleted;
    
    // 6. Optimiser les tables (optionnel, peut être long sur de grosses tables)
    if ($totalDeleted > 1000) {
        echo "- Optimisation des tables...\n";
        $tables = [
            'sec_performance_metrics',
            'sec_failed_login_attempts',
            'sec_alerts',
            'sec_blocked_ips'
        ];
        
        foreach ($tables as $table) {
            try {
                $db->exec("OPTIMIZE TABLE $table");
                echo "  → Table $table optimisée\n";
            } catch (Exception $e) {
                echo "  ⚠ Impossible d'optimiser $table: " . $e->getMessage() . "\n";
            }
        }
    }
    
    // 7. Statistiques finales
    echo "\n=== RÉSUMÉ ===\n";
    echo "Total supprimé: $totalDeleted lignes\n";
    echo "IPs débloquées: $unblocked\n";
    
    // Obtenir les statistiques actuelles
    $stats = [];
    $tables = [
        'sec_alerts' => "SELECT COUNT(*) as total, SUM(resolved = 0) as active FROM sec_alerts",
        'sec_performance_metrics' => "SELECT COUNT(*) as total FROM sec_performance_metrics",
        'sec_failed_login_attempts' => "SELECT COUNT(*) as total FROM sec_failed_login_attempts",
        'sec_blocked_ips' => "SELECT COUNT(*) as total, SUM(permanent = 1) as permanent FROM sec_blocked_ips WHERE unblocked_at IS NULL"
    ];
    
    echo "\nÉtat actuel des tables:\n";
    foreach ($tables as $table => $query) {
        $result = $db->query($query)->fetch(PDO::FETCH_ASSOC);
        if ($table === 'sec_alerts') {
            echo "- $table: {$result['total']} total, {$result['active']} actives\n";
        } elseif ($table === 'sec_blocked_ips') {
            $permanent = $result['permanent'] ?? 0;
            echo "- $table: {$result['total']} bloquées, $permanent permanentes\n";
        } else {
            echo "- $table: {$result['total']} enregistrements\n";
        }
    }
    
    echo "\n[" . date('Y-m-d H:i:s') . "] Nettoyage terminé avec succès\n";
    
} catch (Exception $e) {
    echo "\n❌ ERREUR: " . $e->getMessage() . "\n";
    echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    exit(1);
}