#!/usr/bin/env python3
"""
Test de l'arrêt propre de l'application.
Vérifie qu'aucun processus zombie ne reste après l'arrêt.
"""

import sys
import os
import time
import subprocess
import signal

def check_python_processes():
    """Vérifie les processus Python actifs."""
    try:
        result = subprocess.run(
            ['ps', 'aux'],
            capture_output=True,
            text=True
        )
        
        python_procs = []
        for line in result.stdout.split('\n'):
            if 'python' in line.lower() and ('geniusia' in line or 'main.py' in line):
                python_procs.append(line)
        
        return python_procs
    except Exception as e:
        print(f"❌ Erreur: {e}")
        return []

def test_clean_shutdown():
    """Test de l'arrêt propre."""
    print("🧪 TEST DE L'ARRÊT PROPRE")
    print("=" * 60)
    
    # Vérifier qu'aucun processus n'est actif avant
    print("\n1️⃣ Vérification initiale...")
    procs_before = check_python_processes()
    if procs_before:
        print(f"⚠️  {len(procs_before)} processus Python actifs:")
        for proc in procs_before:
            print(f"   {proc}")
        print("\n⚠️  Nettoyage des processus existants...")
        subprocess.run(['pkill', '-f', 'python.*geniusia'], check=False)
        time.sleep(2)
    else:
        print("✅ Aucun processus actif")
    
    # Lancer l'application en mode headless
    print("\n2️⃣ Lancement de l'application (mode shadow, 5 secondes)...")
    proc = subprocess.Popen(
        ['python3', 'geniusia2/main.py', '--mode', 'shadow', '--headless'],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )
    
    print(f"   PID: {proc.pid}")
    
    # Attendre 5 secondes
    print("   Attente de 5 secondes...")
    time.sleep(5)
    
    # Envoyer SIGINT (Ctrl+C)
    print("\n3️⃣ Envoi de SIGINT (Ctrl+C)...")
    start_time = time.time()
    proc.send_signal(signal.SIGINT)
    
    # Attendre que le processus se termine (max 10 secondes)
    try:
        proc.wait(timeout=10)
        elapsed = time.time() - start_time
        print(f"✅ Processus terminé en {elapsed:.1f}s")
    except subprocess.TimeoutExpired:
        print(f"❌ Timeout après 10 secondes")
        proc.kill()
        elapsed = 10.0
    
    # Attendre un peu pour que les threads se terminent
    time.sleep(2)
    
    # Vérifier qu'aucun processus zombie ne reste
    print("\n4️⃣ Vérification des processus zombies...")
    procs_after = check_python_processes()
    
    if procs_after:
        print(f"❌ {len(procs_after)} processus zombies détectés:")
        for proc in procs_after:
            print(f"   {proc}")
        print("\n⚠️  Nettoyage forcé...")
        subprocess.run(['pkill', '-9', '-f', 'python.*geniusia'], check=False)
        return False
    else:
        print("✅ Aucun processus zombie")
    
    # Résumé
    print("\n" + "=" * 60)
    if elapsed <= 5.0 and not procs_after:
        print("✅ TEST RÉUSSI!")
        print(f"   - Arrêt en {elapsed:.1f}s (< 5s)")
        print(f"   - Aucun processus zombie")
        return True
    else:
        print("❌ TEST ÉCHOUÉ!")
        if elapsed > 5.0:
            print(f"   - Arrêt trop lent: {elapsed:.1f}s (> 5s)")
        if procs_after:
            print(f"   - Processus zombies: {len(procs_after)}")
        return False

if __name__ == "__main__":
    success = test_clean_shutdown()
    sys.exit(0 if success else 1)
