#!/usr/bin/env python3
"""
🎬 Scénarios de test pour Web Sentinel
Automatise différents scénarios de test pour valider le comportement de l'application
"""

import sys
import os
import json
import argparse
import time
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Dict, Any, List

# Ajouter le répertoire parent pour importer web_sentinel
sys.path.insert(0, str(Path(__file__).parent.parent))

from test_accounts import TestAccountManager
from generate_test_license import TestLicenseGenerator

class TestScenarios:
    """Gestionnaire de scénarios de test automatisés"""
    
    def __init__(self):
        self.account_manager = TestAccountManager()
        self.license_generator = TestLicenseGenerator()
        self.config_dir = Path(__file__).parent / "config"
        self.logs_dir = Path(__file__).parent / "logs"
        
        self.logs_dir.mkdir(exist_ok=True)
        
        # Charger la configuration
        config_file = self.config_dir / "test_config.json"
        with open(config_file, 'r', encoding='utf-8') as f:
            self.config = json.load(f)
    
    def log_scenario(self, scenario_name: str, message: str):
        """Logger un message de scénario"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_file = self.logs_dir / f"scenario_{scenario_name}_{datetime.now().strftime('%Y%m%d')}.log"
        
        with open(log_file, 'a', encoding='utf-8') as f:
            f.write(f"[{timestamp}] {message}\n")
        
        print(f"[{timestamp}] {message}")
    
    def scenario_license_expiry(self) -> bool:
        """Scénario: Test comportement licence expirée"""
        scenario_name = "license_expiry"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Test comportement licence expirée")
        
        email = "bruno@taaazzz-prog.fr"
        
        try:
            # 1. Créer une licence qui expire dans 1 jour
            self.log_scenario(scenario_name, f"📋 Étape 1: Licence expire dans 1 jour pour {email}")
            self.account_manager.set_license_expiry(email, 1)
            self.license_generator.generate_license(email, "FREE", 1)
            
            # 2. Simuler approche expiration (7 jours, puis 3, puis 1)
            for days in [7, 3, 1]:
                self.log_scenario(scenario_name, f"⏰ Simulation: Licence expire dans {days} jours")
                self.account_manager.set_license_expiry(email, days)
                time.sleep(1)  # Petit délai pour simuler le temps
            
            # 3. Simuler licence expirée
            self.log_scenario(scenario_name, "❌ Simulation: Licence expirée")
            self.account_manager.set_license_expiry(email, -1)
            
            # 4. Tenter d'utiliser des fonctionnalités avec licence expirée
            self.log_scenario(scenario_name, "🧪 Test: Tentative utilisation avec licence expirée")
            
            # 5. Renouveler la licence
            self.log_scenario(scenario_name, "🔄 Renouvellement de licence")
            self.account_manager.set_license_expiry(email, 365)
            self.license_generator.generate_license(email, "FREE", 365)
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Scénario licence expirée terminé")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def scenario_premium_upgrade(self) -> bool:
        """Scénario: Test upgrade FREE vers PRO"""
        scenario_name = "premium_upgrade"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Test upgrade FREE vers PRO")
        
        email = "bruno@taaazzz-prog.fr"
        
        try:
            # 1. Commencer avec compte FREE
            self.log_scenario(scenario_name, f"📋 Étape 1: Compte FREE pour {email}")
            self.account_manager.update_tier(email, "FREE")
            self.account_manager.update_domains_used(email, 2)  # 2/3 domaines utilisés
            
            # 2. Tenter d'ajouter un 4ème domaine (doit échouer)
            self.log_scenario(scenario_name, "🧪 Test: Tentative d'ajouter 4ème domaine (doit échouer)")
            self.account_manager.update_domains_used(email, 4)  # Devrait déclencher limite
            
            # 3. Upgrade vers PRO
            self.log_scenario(scenario_name, "⬆️ Upgrade vers PRO")
            self.account_manager.update_tier(email, "PRO")
            self.license_generator.generate_license(email, "PRO", 365)
            
            # 4. Tester nouvelles fonctionnalités PRO
            self.log_scenario(scenario_name, "🧪 Test: Fonctionnalités PRO disponibles")
            self.account_manager.update_domains_used(email, 50)  # Pas de limite PRO
            
            # 5. Tester export HTML (disponible en PRO)
            self.log_scenario(scenario_name, "📊 Test: Export HTML disponible")
            
            # 6. Tester tests invasifs (disponibles en PRO)
            self.log_scenario(scenario_name, "🔍 Test: Tests invasifs disponibles")
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Scénario upgrade terminé")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def scenario_enterprise_features(self) -> bool:
        """Scénario: Test fonctionnalités ENTERPRISE"""
        scenario_name = "enterprise_features"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Test fonctionnalités ENTERPRISE")
        
        email = "enterprise@taaazzz.com"
        
        try:
            # 1. Upgrade vers ENTERPRISE
            self.log_scenario(scenario_name, f"📋 Étape 1: Upgrade {email} vers ENTERPRISE")
            self.account_manager.update_tier(email, "ENTERPRISE")
            self.license_generator.generate_license(email, "ENTERPRISE", 365)
            
            # 2. Tester API access
            self.log_scenario(scenario_name, "🔌 Test: Accès API disponible")
            
            # 3. Tester multi-utilisateurs
            self.log_scenario(scenario_name, "👥 Test: Multi-utilisateurs disponible")
            
            # 4. Tester export PDF
            self.log_scenario(scenario_name, "📄 Test: Export PDF disponible")
            
            # 5. Tester domaines illimités
            self.log_scenario(scenario_name, "🌐 Test: Domaines illimités")
            self.account_manager.update_domains_used(email, 500)
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Scénario ENTERPRISE terminé")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def scenario_government_airgap(self) -> bool:
        """Scénario: Test mode GOVERNMENT air-gap"""
        scenario_name = "government_airgap"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Test mode GOVERNMENT air-gap")
        
        email = "gov@taaazzz.com"
        
        try:
            # 1. Créer compte GOVERNMENT
            self.log_scenario(scenario_name, f"📋 Étape 1: Création compte GOVERNMENT {email}")
            self.account_manager.create_account(email, "Government User", "GOVERNMENT")
            self.license_generator.generate_license(email, "GOVERNMENT", 1095)  # 3 ans
            
            # 2. Tester mode air-gap
            self.log_scenario(scenario_name, "🔒 Test: Mode air-gap activé")
            
            # 3. Tester audit trail
            self.log_scenario(scenario_name, "📝 Test: Audit trail chiffré")
            
            # 4. Tester gestion utilisateurs locale
            self.log_scenario(scenario_name, "👥 Test: Gestion utilisateurs locale")
            
            # 5. Tester compliance gouvernementale
            self.log_scenario(scenario_name, "📋 Test: Compliance gouvernementale")
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Scénario GOVERNMENT terminé")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def scenario_multi_tier_comparison(self) -> bool:
        """Scénario: Comparaison de tous les tiers"""
        scenario_name = "multi_tier_comparison"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Comparaison tous les tiers")
        
        tiers = ["FREE", "PRO", "ENTERPRISE", "GOVERNMENT", "FINANCE", "MEDICAL"]
        base_email = "test_{tier}@taaazzz.com"
        
        try:
            for tier in tiers:
                email = base_email.format(tier=tier.lower())
                
                self.log_scenario(scenario_name, f"📋 Test tier {tier}: {email}")
                
                # Créer ou mettre à jour le compte
                if not self.account_manager.find_account(email):
                    self.account_manager.create_account(email, f"Test {tier} User", tier)
                else:
                    self.account_manager.update_tier(email, tier)
                
                # Générer licence appropriée
                days = 365 if tier not in ["GOVERNMENT", "FINANCE", "MEDICAL"] else 1095
                self.license_generator.generate_license(email, tier, days)
                
                # Tester fonctionnalités spécifiques au tier
                tier_config = self.config["tiers"][tier]
                
                if tier_config.get("domains_limit"):
                    self.account_manager.update_domains_used(email, tier_config["domains_limit"] - 1)
                else:
                    self.account_manager.update_domains_used(email, 100)  # Test illimité
                
                self.log_scenario(scenario_name, f"   ✅ {tier}: Prix {tier_config['price']}€, Features: {len(tier_config.get('export_formats', []))} formats")
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Comparaison tiers terminée")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def scenario_stress_test(self) -> bool:
        """Scénario: Test de charge"""
        scenario_name = "stress_test"
        self.log_scenario(scenario_name, "🎬 DÉBUT - Test de charge")
        
        try:
            # Créer plusieurs comptes de test
            for i in range(10):
                email = f"stress_test_{i}@taaazzz.com"
                tier = ["FREE", "PRO", "ENTERPRISE"][i % 3]
                
                self.log_scenario(scenario_name, f"📋 Création compte {i+1}/10: {email} ({tier})")
                
                if not self.account_manager.find_account(email):
                    self.account_manager.create_account(email, f"Stress Test User {i}", tier)
                
                self.license_generator.generate_license(email, tier, 365)
                
                # Simuler usage
                domains_used = (i + 1) * 5
                self.account_manager.update_domains_used(email, domains_used)
            
            self.log_scenario(scenario_name, "✅ SUCCÈS - Test de charge terminé")
            return True
            
        except Exception as e:
            self.log_scenario(scenario_name, f"❌ ERREUR - {e}")
            return False
    
    def run_scenario(self, scenario_name: str) -> bool:
        """Exécuter un scénario spécifique"""
        scenarios = {
            "license_expiry": self.scenario_license_expiry,
            "premium_upgrade": self.scenario_premium_upgrade,
            "enterprise_features": self.scenario_enterprise_features,
            "government_airgap": self.scenario_government_airgap,
            "multi_tier_comparison": self.scenario_multi_tier_comparison,
            "stress_test": self.scenario_stress_test,
        }
        
        if scenario_name not in scenarios:
            print(f"❌ Scénario inconnu: {scenario_name}")
            print(f"   Disponibles: {list(scenarios.keys())}")
            return False
        
        return scenarios[scenario_name]()
    
    def run_all_scenarios(self) -> Dict[str, bool]:
        """Exécuter tous les scénarios"""
        print("🎬 EXÉCUTION DE TOUS LES SCÉNARIOS")
        print("=" * 80)
        
        results = {}
        scenarios = [
            "license_expiry",
            "premium_upgrade", 
            "enterprise_features",
            "government_airgap",
            "multi_tier_comparison",
            "stress_test"
        ]
        
        for scenario in scenarios:
            print(f"\n🎬 Exécution: {scenario}")
            results[scenario] = self.run_scenario(scenario)
            print(f"{'✅ SUCCÈS' if results[scenario] else '❌ ÉCHEC'}: {scenario}")
        
        print("\n" + "=" * 80)
        print("📊 RÉSULTATS FINAUX:")
        
        success_count = sum(1 for success in results.values() if success)
        total_count = len(results)
        
        for scenario, success in results.items():
            status = "✅" if success else "❌"
            print(f"   {status} {scenario}")
        
        print(f"\n🎯 SCORE: {success_count}/{total_count} scénarios réussis")
        
        return results


def main():
    parser = argparse.ArgumentParser(description="🎬 Scénarios de test Web Sentinel")
    parser.add_argument("--scenario", help="Scénario à exécuter", 
                       choices=["license_expiry", "premium_upgrade", "enterprise_features", 
                               "government_airgap", "multi_tier_comparison", "stress_test", "all"])
    parser.add_argument("--list", action="store_true", help="Lister les scénarios disponibles")
    
    args = parser.parse_args()
    
    scenarios = TestScenarios()
    
    if args.list:
        print("🎬 SCÉNARIOS DE TEST DISPONIBLES:")
        print("=" * 50)
        print("  license_expiry       - Test comportement licence expirée")
        print("  premium_upgrade      - Test upgrade FREE vers PRO")
        print("  enterprise_features  - Test fonctionnalités ENTERPRISE")
        print("  government_airgap    - Test mode GOVERNMENT air-gap")
        print("  multi_tier_comparison- Comparaison tous les tiers")
        print("  stress_test          - Test de charge")
        print("  all                  - Exécuter tous les scénarios")
        return
    
    if not args.scenario:
        print("❌ --scenario requis")
        print("\n📋 AIDE RAPIDE:")
        print("  --scenario license_expiry")
        print("  --scenario premium_upgrade")
        print("  --scenario all")
        print("  --list")
        return
    
    if args.scenario == "all":
        scenarios.run_all_scenarios()
    else:
        success = scenarios.run_scenario(args.scenario)
        if success:
            print(f"✅ Scénario {args.scenario} terminé avec succès")
        else:
            print(f"❌ Scénario {args.scenario} échoué")


if __name__ == "__main__":
    main()