#!/usr/bin/env python3
"""
🗄️ Setup base de données de test pour Web Sentinel
Configure une base de données MySQL de test avec données d'exemple
"""

import sys
import os
import json
import mysql.connector
from datetime import datetime, 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))

class TestDatabaseSetup:
    """Setup base de données de test"""
    
    def __init__(self):
        self.config_dir = Path(__file__).parent / "config"
        self.config_file = self.config_dir / "test_config.json"
        self.accounts_file = self.config_dir / "accounts.json"
        
        # Charger configuration
        with open(self.config_file, 'r', encoding='utf-8') as f:
            self.config = json.load(f)
        
        with open(self.accounts_file, 'r', encoding='utf-8') as f:
            self.accounts_data = json.load(f)
        
        self.db_config = self.config["database"]
    
    def create_connection(self, include_db=True):
        """Créer connexion MySQL"""
        config = {
            'host': self.db_config['host'],
            'port': self.db_config['port'],
            'user': self.db_config['user'],
            'password': self.db_config['password']
        }
        
        if include_db:
            config['database'] = self.db_config['name']
        
        return mysql.connector.connect(**config)
    
    def create_test_database(self) -> bool:
        """Créer la base de données de test"""
        try:
            # Connexion sans spécifier la base de données
            conn = self.create_connection(include_db=False)
            cursor = conn.cursor()
            
            # Créer la base de données
            cursor.execute(f"CREATE DATABASE IF NOT EXISTS {self.db_config['name']}")
            cursor.execute(f"USE {self.db_config['name']}")
            
            print(f"✅ Base de données '{self.db_config['name']}' créée")
            
            cursor.close()
            conn.close()
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur création base de données: {e}")
            return False
    
    def create_test_tables(self) -> bool:
        """Créer les tables de test"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor()
            
            # Table utilisateurs
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS users (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    email VARCHAR(255) UNIQUE NOT NULL,
                    name VARCHAR(255) NOT NULL,
                    password_hash VARCHAR(255),
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    last_login TIMESTAMP NULL,
                    status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
                    email_verified BOOLEAN DEFAULT FALSE
                )
            """)
            
            # Table abonnements
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS subscriptions (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    user_id INT NOT NULL,
                    tier ENUM('FREE', 'PRO', 'ENTERPRISE', 'GOVERNMENT', 'FINANCE', 'MEDICAL') NOT NULL,
                    status ENUM('active', 'inactive', 'expired', 'cancelled') DEFAULT 'active',
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    expires_at TIMESTAMP NULL,
                    auto_renew BOOLEAN DEFAULT TRUE,
                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
                )
            """)
            
            # Table utilisation
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS usage_stats (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    user_id INT NOT NULL,
                    domains_scanned INT DEFAULT 0,
                    scans_count INT DEFAULT 0,
                    last_scan TIMESTAMP NULL,
                    monthly_domains INT DEFAULT 0,
                    monthly_scans INT DEFAULT 0,
                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
                )
            """)
            
            # Table licences
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS licenses (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    user_id INT NOT NULL,
                    license_key VARCHAR(255) UNIQUE NOT NULL,
                    license_file TEXT,
                    issued_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    expires_at TIMESTAMP NOT NULL,
                    status ENUM('active', 'expired', 'revoked') DEFAULT 'active',
                    tier VARCHAR(50) NOT NULL,
                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
                )
            """)
            
            # Table logs de test
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS test_logs (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    test_type VARCHAR(100) NOT NULL,
                    user_email VARCHAR(255),
                    action VARCHAR(255) NOT NULL,
                    details TEXT,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    success BOOLEAN DEFAULT TRUE
                )
            """)
            
            conn.commit()
            print("✅ Tables de test créées")
            
            cursor.close()
            conn.close()
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur création tables: {e}")
            return False
    
    def insert_test_data(self) -> bool:
        """Insérer les données de test"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor()
            
            # Insérer utilisateurs de test
            for account in self.accounts_data["test_accounts"]:
                # Vérifier si l'utilisateur existe
                cursor.execute("SELECT id FROM users WHERE email = %s", (account["email"],))
                existing = cursor.fetchone()
                
                if not existing:
                    cursor.execute("""
                        INSERT INTO users (email, name, created_at, last_login, status, email_verified)
                        VALUES (%s, %s, %s, %s, %s, %s)
                    """, (
                        account["email"],
                        account["name"],
                        account["created_at"],
                        account["last_login"],
                        account["status"],
                        True
                    ))
                    user_id = cursor.lastrowid
                else:
                    user_id = existing[0]
                
                # Abonnement
                cursor.execute("SELECT id FROM subscriptions WHERE user_id = %s", (user_id,))
                if not cursor.fetchone():
                    cursor.execute("""
                        INSERT INTO subscriptions (user_id, tier, status, expires_at)
                        VALUES (%s, %s, %s, %s)
                    """, (
                        user_id,
                        account["tier"],
                        account["status"],
                        account["license_expires"]
                    ))
                
                # Statistiques d'utilisation
                cursor.execute("SELECT id FROM usage_stats WHERE user_id = %s", (user_id,))
                if not cursor.fetchone():
                    cursor.execute("""
                        INSERT INTO usage_stats (user_id, domains_scanned, scans_count, last_scan)
                        VALUES (%s, %s, %s, %s)
                    """, (
                        user_id,
                        account["domains_used"],
                        account["domains_used"] * 2,  # Estimation
                        account["last_login"]
                    ))
            
            conn.commit()
            print("✅ Données de test insérées")
            
            cursor.close()
            conn.close()
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur insertion données: {e}")
            return False
    
    def log_test_action(self, test_type: str, user_email: str, action: str, 
                       details: str = None, success: bool = True) -> bool:
        """Logger une action de test"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor()
            
            cursor.execute("""
                INSERT INTO test_logs (test_type, user_email, action, details, success)
                VALUES (%s, %s, %s, %s, %s)
            """, (test_type, user_email, action, details, success))
            
            conn.commit()
            cursor.close()
            conn.close()
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur log: {e}")
            return False
    
    def get_user_stats(self, email: str) -> Dict[str, Any]:
        """Obtenir les statistiques d'un utilisateur"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor(dictionary=True)
            
            cursor.execute("""
                SELECT u.*, s.tier, s.status as subscription_status, s.expires_at,
                       us.domains_scanned, us.scans_count, us.last_scan
                FROM users u
                LEFT JOIN subscriptions s ON u.id = s.user_id
                LEFT JOIN usage_stats us ON u.id = us.user_id
                WHERE u.email = %s
            """, (email,))
            
            result = cursor.fetchone()
            cursor.close()
            conn.close()
            
            return result or {}
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur récupération stats: {e}")
            return {}
    
    def update_user_usage(self, email: str, domains_scanned: int, scans_count: int) -> bool:
        """Mettre à jour l'utilisation d'un utilisateur"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor()
            
            cursor.execute("""
                UPDATE usage_stats us
                JOIN users u ON us.user_id = u.id
                SET us.domains_scanned = %s, us.scans_count = %s, us.last_scan = NOW()
                WHERE u.email = %s
            """, (domains_scanned, scans_count, email))
            
            conn.commit()
            cursor.close()
            conn.close()
            
            print(f"✅ Usage mis à jour pour {email}: {domains_scanned} domaines, {scans_count} scans")
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur mise à jour usage: {e}")
            return False
    
    def cleanup_test_data(self) -> bool:
        """Nettoyer les données de test"""
        try:
            conn = self.create_connection()
            cursor = conn.cursor()
            
            # Supprimer dans l'ordre (contraintes foreign key)
            tables = ["test_logs", "licenses", "usage_stats", "subscriptions", "users"]
            
            for table in tables:
                cursor.execute(f"DELETE FROM {table}")
                print(f"✅ Table {table} vidée")
            
            conn.commit()
            cursor.close()
            conn.close()
            
            print("✅ Données de test nettoyées")
            return True
            
        except mysql.connector.Error as e:
            print(f"❌ Erreur nettoyage: {e}")
            return False
    
    def setup_complete_test_environment(self) -> bool:
        """Setup complet de l'environnement de test"""
        print("🗄️ SETUP ENVIRONNEMENT DE TEST COMPLET")
        print("=" * 60)
        
        steps = [
            ("Création base de données", self.create_test_database),
            ("Création tables", self.create_test_tables),
            ("Insertion données test", self.insert_test_data),
        ]
        
        for step_name, step_func in steps:
            print(f"📋 {step_name}...")
            if not step_func():
                print(f"❌ Échec: {step_name}")
                return False
        
        print("=" * 60)
        print("✅ ENVIRONNEMENT DE TEST PRÊT!")
        print(f"   Base de données: {self.db_config['name']}")
        print(f"   Host: {self.db_config['host']}:{self.db_config['port']}")
        print(f"   Comptes test: {len(self.accounts_data['test_accounts'])}")
        
        return True


def main():
    import argparse
    
    parser = argparse.ArgumentParser(description="🗄️ Setup base de données de test Web Sentinel")
    parser.add_argument("--setup", action="store_true", help="Setup complet environnement")
    parser.add_argument("--cleanup", action="store_true", help="Nettoyer données de test")
    parser.add_argument("--stats", help="Voir stats utilisateur par email")
    parser.add_argument("--log", nargs=4, metavar=("TYPE", "EMAIL", "ACTION", "DETAILS"), 
                       help="Logger une action de test")
    
    args = parser.parse_args()
    
    db_setup = TestDatabaseSetup()
    
    if args.setup:
        db_setup.setup_complete_test_environment()
    
    elif args.cleanup:
        print("⚠️ Êtes-vous sûr de vouloir supprimer toutes les données de test ? (y/N)")
        response = input().lower()
        if response == 'y':
            db_setup.cleanup_test_data()
        else:
            print("❌ Annulé")
    
    elif args.stats:
        stats = db_setup.get_user_stats(args.stats)
        if stats:
            print(f"📊 STATS UTILISATEUR: {args.stats}")
            print("=" * 50)
            for key, value in stats.items():
                print(f"   {key}: {value}")
        else:
            print(f"❌ Utilisateur {args.stats} introuvable")
    
    elif args.log:
        test_type, email, action, details = args.log
        db_setup.log_test_action(test_type, email, action, details)
        print(f"✅ Action loggée: {action} pour {email}")
    
    else:
        print("🗄️ AIDE RAPIDE:")
        print("  --setup                           # Setup complet environnement")
        print("  --cleanup                         # Nettoyer données de test")
        print("  --stats bruno@taaazzz-prog.fr     # Voir stats utilisateur")
        print("  --log test_type email action details # Logger action")


if __name__ == "__main__":
    main()