#!/usr/bin/env python3
"""
🔐 Générateur de licences de test pour Web Sentinel
Génère des fichiers .lic valides pour tester le système de licence
"""

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

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

try:
    from web_sentinel.license.license_generator import LicenseGenerator
    from web_sentinel.license.crypto_manager import CryptoManager
except ImportError as e:
    print(f"❌ Erreur d'import: {e}")
    print("   Assurez-vous que le module web_sentinel.license est disponible")
    sys.exit(1)

class TestLicenseGenerator:
    """Générateur de licences de test"""
    
    def __init__(self):
        self.config_dir = Path(__file__).parent / "config"
        self.licenses_dir = Path(__file__).parent / "licenses" 
        self.logs_dir = Path(__file__).parent / "logs"
        
        # Créer les répertoires si nécessaire
        self.licenses_dir.mkdir(exist_ok=True)
        self.logs_dir.mkdir(exist_ok=True)
        
        self.config = self._load_config()
        
        # Initialiser le générateur de licence
        try:
            self.crypto_manager = CryptoManager()
            self.license_generator = LicenseGenerator()
        except Exception as e:
            print(f"❌ Erreur initialisation crypto: {e}")
            sys.exit(1)
    
    def _load_config(self) -> Dict[str, Any]:
        """Charger la configuration de test"""
        config_file = self.config_dir / "test_config.json"
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        except FileNotFoundError:
            print(f"❌ Fichier de configuration non trouvé: {config_file}")
            sys.exit(1)
    
    def generate_license(self, email: str, tier: str, days: int = 365, 
                        domains_limit: Optional[int] = None,
                        features: Optional[Dict[str, Any]] = None) -> str:
        """Générer une licence de test"""
        
        if tier not in self.config.get("tiers", {}):
            raise ValueError(f"Tier {tier} invalide. Disponibles: {list(self.config.get('tiers', {}).keys())}")
        
        tier_config = self.config["tiers"][tier]
        
        # Préparer les données de licence
        license_data = {
            "email": email,
            "tier": tier,
            "domains_limit": domains_limit or tier_config["domains_limit"],
            "features": features or {
                "export_formats": tier_config["export_formats"],
                "invasive_tests": tier_config["invasive_tests"],
                "api_access": tier_config["api_access"],
                "multi_user": tier_config["multi_user"]
            },
            "issued_at": datetime.now(timezone.utc).isoformat(),
            "expires_at": (datetime.now(timezone.utc) + timedelta(days=days)).isoformat(),
            "license_type": "test",
            "issuer": "Taaazzz Test Environment"
        }
        
        # Ajouter les features spéciales pour les tiers premium
        if "compliance" in tier_config:
            license_data["features"]["compliance"] = tier_config["compliance"]
        if "air_gap" in tier_config:
            license_data["features"]["air_gap"] = tier_config["air_gap"]
        
        try:
            # Générer la licence
            license_content = self.license_generator.generate_license(license_data)
            
            # Nom du fichier
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            license_filename = f"{email.replace('@', '_at_').replace('.', '_')}_{tier}_{timestamp}.lic"
            license_path = self.licenses_dir / license_filename
            
            # Sauvegarder la licence
            with open(license_path, 'w', encoding='utf-8') as f:
                f.write(license_content)
            
            # Sauvegarder les métadonnées
            metadata_path = license_path.with_suffix('.json')
            with open(metadata_path, 'w', encoding='utf-8') as f:
                json.dump(license_data, f, indent=2, ensure_ascii=False)
            
            print(f"✅ Licence générée: {license_filename}")
            print(f"   📧 Email: {email}")
            print(f"   🎯 Tier: {tier} ({tier_config['price']}€)")
            print(f"   ⏰ Valide: {days} jours")
            print(f"   📁 Fichier: {license_path}")
            print(f"   📄 Métadonnées: {metadata_path}")
            
            return str(license_path)
            
        except Exception as e:
            print(f"❌ Erreur génération licence: {e}")
            raise
    
    def validate_license(self, license_file: str) -> bool:
        """Valider une licence de test"""
        license_path = Path(license_file)
        
        if not license_path.exists():
            print(f"❌ Fichier licence introuvable: {license_file}")
            return False
        
        try:
            with open(license_path, 'r', encoding='utf-8') as f:
                license_content = f.read()
            
            # Valider la licence
            from web_sentinel.license.license_validator import LicenseValidator
            validator = LicenseValidator()
            
            is_valid, license_data, error = validator.validate_license(license_content)
            
            if is_valid:
                print(f"✅ Licence valide: {license_file}")
                print(f"   📧 Email: {license_data.get('email')}")
                print(f"   🎯 Tier: {license_data.get('tier')}")
                print(f"   ⏰ Expire: {license_data.get('expires_at')}")
                return True
            else:
                print(f"❌ Licence invalide: {error}")
                return False
                
        except Exception as e:
            print(f"❌ Erreur validation: {e}")
            return False
    
    def list_licenses(self):
        """Lister toutes les licences générées"""
        print("\n🔐 LICENCES DE TEST GÉNÉRÉES:")
        print("=" * 100)
        
        license_files = list(self.licenses_dir.glob("*.lic"))
        
        if not license_files:
            print("   Aucune licence générée")
            return
        
        for license_file in sorted(license_files):
            metadata_file = license_file.with_suffix('.json')
            
            if metadata_file.exists():
                try:
                    with open(metadata_file, 'r', encoding='utf-8') as f:
                        metadata = json.load(f)
                    
                    expires_at = datetime.fromisoformat(metadata['expires_at'].replace('Z', '+00:00'))
                    days_left = (expires_at - datetime.now(timezone.utc)).days
                    
                    status_icon = "❌" if days_left <= 0 else "⚠️" if days_left <= 7 else "✅"
                    
                    print(f"{status_icon} {license_file.name:<50} | {metadata['email']:<30} | {metadata['tier']:<12} | {days_left:>3}j")
                    
                except Exception as e:
                    print(f"❌ {license_file.name:<50} | Erreur lecture métadonnées: {e}")
            else:
                print(f"⚠️ {license_file.name:<50} | Métadonnées manquantes")
        
        print("=" * 100)
    
    def create_scenario_licenses(self):
        """Créer des licences pour différents scénarios de test"""
        scenarios = [
            # Licence qui expire demain
            ("bruno@taaazzz-prog.fr", "FREE", 1, "Expire demain"),
            
            # Licence qui expire dans 7 jours 
            ("test@taaazzz.com", "PRO", 7, "Expire dans 7 jours"),
            
            # Licence expirée (il y a 5 jours)
            ("expired@taaazzz.com", "FREE", -5, "Expirée"),
            
            # Licence longue durée PRO
            ("premium@taaazzz.com", "PRO", 365, "PRO standard"),
            
            # Licence ENTERPRISE
            ("enterprise@taaazzz.com", "ENTERPRISE", 365, "Enterprise"),
            
            # Licence GOVERNMENT
            ("gov@taaazzz.com", "GOVERNMENT", 1095, "Government (3 ans)"),
        ]
        
        print("🎬 CRÉATION DES SCÉNARIOS DE TEST:")
        print("=" * 80)
        
        for email, tier, days, description in scenarios:
            try:
                # Ajuster les dates pour les licences "expirées"
                if days < 0:
                    # Créer une licence qui était valide mais qui a expiré
                    issued_date = datetime.now(timezone.utc) + timedelta(days=days-365)
                    expires_date = datetime.now(timezone.utc) + timedelta(days=days)
                    
                    license_data = {
                        "email": email,
                        "tier": tier,
                        "issued_at": issued_date.isoformat(),
                        "expires_at": expires_date.isoformat(),
                        "license_type": "test_expired",
                        "issuer": "Taaazzz Test Environment"
                    }
                    
                    # Générer manuellement pour contrôler les dates
                    license_content = self.license_generator.generate_license(license_data)
                    
                    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                    license_filename = f"{email.replace('@', '_at_').replace('.', '_')}_{tier}_EXPIRED_{timestamp}.lic"
                    license_path = self.licenses_dir / license_filename
                    
                    with open(license_path, 'w', encoding='utf-8') as f:
                        f.write(license_content)
                    
                    metadata_path = license_path.with_suffix('.json')
                    with open(metadata_path, 'w', encoding='utf-8') as f:
                        json.dump(license_data, f, indent=2, ensure_ascii=False)
                    
                    print(f"❌ {description}: {license_filename}")
                else:
                    license_path = self.generate_license(email, tier, days)
                    print(f"✅ {description}: {Path(license_path).name}")
                    
            except Exception as e:
                print(f"❌ Erreur {description}: {e}")
        
        print("=" * 80)


def main():
    parser = argparse.ArgumentParser(description="🔐 Générateur de licences de test Web Sentinel")
    parser.add_argument("--email", help="Email pour la licence")
    parser.add_argument("--tier", help="Tier de licence (FREE/PRO/ENTERPRISE/GOVERNMENT/FINANCE/MEDICAL)")
    parser.add_argument("--days", type=int, default=365, help="Durée en jours (défaut: 365)")
    parser.add_argument("--domains", type=int, help="Limite de domaines (optionnel)")
    parser.add_argument("--validate", help="Valider une licence existante")
    parser.add_argument("--list", action="store_true", help="Lister toutes les licences")
    parser.add_argument("--scenarios", action="store_true", help="Créer licences pour scénarios de test")
    
    args = parser.parse_args()
    
    generator = TestLicenseGenerator()
    
    if args.list:
        generator.list_licenses()
        return
    
    if args.scenarios:
        generator.create_scenario_licenses()
        return
    
    if args.validate:
        generator.validate_license(args.validate)
        return
    
    if not args.email or not args.tier:
        print("❌ --email et --tier requis pour générer une licence")
        print("\n📋 AIDE RAPIDE:")
        print("  --email bruno@taaazzz-prog.fr --tier PRO --days 365")
        print("  --validate licenses/bruno_at_taaazzz-prog_fr_PRO_20251015_120000.lic")
        print("  --list")
        print("  --scenarios")
        parser.print_help()
        return
    
    try:
        generator.generate_license(args.email, args.tier, args.days, args.domains)
    except Exception as e:
        print(f"❌ Erreur: {e}")


if __name__ == "__main__":
    main()