"""
Core du SDK Lescopr - VERSION REFACTORISÉE AVEC ARCHITECTURE CLEAN
"""
import os
import sys
import time
import json
import requests
import threading

from ..filesystem import ProjectAnalyzer, ConfigManager
from ..monitoring.logger import logger
from ..network.grpc import GrpcClient


class Lescopr:
    """
    Core du SDK Lescopr - Gestionnaire central de toutes les opérations
    
    ARCHITECTURE CLEAN:
    - ✅ SEULE queue centrale pour logs (_pending_logs_for_server)
    - ✅ send_log() = point d'entrée unifié qui délègue
    - ✅ Séparation claire gRPC direct vs daemon
    - ✅ Auto-discovery robuste
    """
    
    #BASE_URL = 'http://localhost:8000/api/v1'
    BASE_URL = 'https://api.lescopr.com/api/v1'
    VALID_ENVIRONMENTS = ['development', 'production']

    def __init__(self, api_key=None, sdk_key=None, environment='development', auto_logging=True, auto_grpc=True):
        self.api_key = api_key
        self.environment = environment
        self.sdk_key = sdk_key
        self.sdk_id = None
        self.project_name = None
        self.grpc_client = None
        self.config_manager = ConfigManager()
        self.logging_handler = None
        self.auto_grpc = auto_grpc

        # ✅ SEULE QUEUE CENTRALE DU SYSTÈME
        self._pending_logs_for_server = []
        self._logs_lock = threading.RLock()

        if not api_key or not sdk_key:
            self._load_config()
        
        if auto_logging and self.auto_grpc and self.sdk_id:
            self._setup_auto_logging()

    def _load_config(self):
        """Charge la configuration depuis le fichier de config"""
        try:
            config = self.config_manager.load()
            if not config and not self.api_key:
                logger('warning', "[LESCOPR] Config non trouvée. Utilisation des paramètres par défaut.")
                return
            
            self.api_key = self.api_key or config.get('api_key')
            self.sdk_key = self.sdk_key or config.get('sdk_key')
            self.environment = self.environment or config.get('environment', 'development')
            self.sdk_id = config.get('sdk_id')
            self.project_name = config.get('project_name')
            
            logger('info', f"[LESCOPR] Configuration chargée - Projet: {self.project_name}")
            logger('debug', f"[LESCOPR] SDK ID: {self.sdk_id}")
            logger('debug', f"[LESCOPR] SDK Key: {'***' + self.sdk_key[-4:] if self.sdk_key else 'Non défini'}")
            
        except Exception as e:
            logger('error', f"[LESCOPR] Erreur chargement config: {e}")

    def _validate_config(self):
        if not self.api_key:
            raise ValueError("Clé API requise")
        if self.environment not in self.VALID_ENVIRONMENTS:
            raise ValueError(f"Environnement invalide: {self.environment}")

    def initialize(self):
        self._validate_config()
        
        analyzer = ProjectAnalyzer()
        project_analysis = analyzer.analyze()
        if not project_analysis:
            raise ValueError("Échec analyse projet")
                
        response = requests.post(
            f"{self.BASE_URL}/sdk/verify/",
            headers={
                'X-API-Key': self.api_key,
                'X-SDK-Key': self.sdk_key,
                'Content-Type': 'application/json'
            },
            json=project_analysis
        )
        
        if not response.ok:
            error_msg = response.json().get('message', 'Erreur inconnue') if response.ok else response.text
            raise ValueError(f"Vérification échouée: {error_msg}")
                
        response_data = response.json()
        data = response_data.get('data', {})
        
        self.sdk_id = data.get('id')
        self.project_name = project_analysis.get('project_name', 'Projet inconnu')
        self.project_stack = [fw['name'] for fw in project_analysis.get('detected_frameworks', [])]
        
        if not self.sdk_id:
            raise ValueError("SDK ID non reçu")
        
        config = {
            'sdk_id': self.sdk_id,
            'sdk_key': self.sdk_key,
            'api_key': self.api_key,
            'environment': self.environment,
            'project_name': self.project_name,
            'project_stack': self.project_stack,
        }
        
        self._save_config(config)
        return config

    def setup_logging(self, level="INFO", capture_all_logs=True):
        """Configuration avancée du logging avec gRPC"""
        try:
            import logging
            from datetime import datetime as dt
            
            if not self.grpc_client:
                logger('warning', "[LESCOPR] gRPC non disponible pour les logs")
                return False
            
            class LescoprHandler(logging.Handler):
                def __init__(self, lescopr_instance):
                    super().__init__()
                    self.lescopr = lescopr_instance
                    self.log_buffer = []
                    self.last_send = time.time()
                    self.send_interval = 10
                
                def emit(self, record):
                    try:
                        if record.name.startswith('lescopr'):
                            return
                        
                        log_entry = {
                            'timestamp': dt.fromtimestamp(record.created).isoformat(),
                            'level': record.levelname,
                            'message': self.format(record),
                            'module': record.module,
                            'function': record.funcName,
                            'line': record.lineno,
                            'context': {
                                'pathname': record.pathname,
                                'filename': record.filename,
                                'process': record.process,
                                'thread': record.thread,
                                'logger_name': record.name
                            }
                        }
                        
                        if record.exc_info:
                            log_entry['context']['exception'] = self.formatException(record.exc_info)
                        
                        self.log_buffer.append(log_entry)
                        
                        # Envoi périodique
                        current_time = time.time()
                        if current_time - self.last_send >= self.send_interval:
                            self._send_logs()
                            self.last_send = current_time
                            
                    except Exception:
                        pass
                
                def _send_logs(self):
                    """✅ UTILISE LA QUEUE CENTRALE UNIFIÉE"""
                    if not self.log_buffer:
                        return
                    
                    try:
                        for log_entry in self.log_buffer:
                            self.lescopr.add_pending_log(log_entry)
                        
                        logger('debug', f"[LESCOPR] {len(self.log_buffer)} logs ajoutés à la queue")
                        self.log_buffer.clear()
                        
                    except Exception as e:
                        logger('debug', f"[LESCOPR] Erreur envoi logs: {e}")
                
                def close(self):
                    self._send_logs()
                    super().close()
            
            lescopr_handler = LescoprHandler(self)
            formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
            lescopr_handler.setFormatter(formatter)
            
            if isinstance(level, str):
                level = getattr(logging, level.upper(), logging.INFO)
            lescopr_handler.setLevel(level)
            
            if capture_all_logs:
                root_logger = logging.getLogger()
                root_logger.addHandler(lescopr_handler)
                if root_logger.level > level:
                    root_logger.setLevel(level)
                    
                try:
                    django_logger = logging.getLogger('django')
                    django_logger.addHandler(lescopr_handler)
                    django_logger.setLevel(level)
                except:
                    pass
            else:
                app_logger = logging.getLogger('__main__')
                app_logger.addHandler(lescopr_handler)
                app_logger.setLevel(level)
            
            self.logging_handler = lescopr_handler
            logger('info', f"[LESCOPR] Logging configuré - Niveau: {logging.getLevelName(level)}")
            return True
            
        except Exception as e:
            logger('error', f"[LESCOPR] Erreur setup logging: {e}")
            return False

    def _save_config(self, config):
        self.config_manager.save(config)

    def _setup_auto_logging(self):
        """Configuration automatique SILENCIEUSE - pas de doubles"""
        try:
            if hasattr(self, '_auto_logging_setup'):
                return
            
            self._auto_logging_setup = True
            
            if not self.sdk_id or not self.sdk_key:
                return
            
            if not self.grpc_client:
                success = self.start_grpc_streaming()
                if not success:
                    return
            
            import threading
            def delayed_setup():
                time.sleep(2)
                self.setup_logging(level="INFO", capture_all_logs=True)
    
            thread = threading.Thread(target=delayed_setup, daemon=True)
            thread.start()
            
        except Exception:
            pass  # Échec silencieux
    
    def start_grpc_streaming(self, host=None, port=None) -> bool:
        """Démarre la connexion gRPC en streaming"""
        try:
            logger('info', f"[LESCOPR] ==> Début start_grpc_streaming(host={host}, port={port})")
            
            # ✅ VÉRIFICATIONS DÉTAILLÉES
            if not self.sdk_id:
                logger('error', "[LESCOPR] ❌ SDK ID requis pour démarrer gRPC")
                logger('debug', f"[LESCOPR] SDK ID actuel: '{self.sdk_id}'")
                return False
                
            if not self.sdk_key:
                logger('error', "[LESCOPR] ❌ SDK Key requis pour démarrer gRPC")
                logger('debug', f"[LESCOPR] SDK Key présent: {bool(self.sdk_key)}")
                return False
            
            logger('info', f"[LESCOPR] ==> SDK ID: {self.sdk_id}")
            logger('info', f"[LESCOPR] ==> SDK Key: ***{self.sdk_key[-4:] if self.sdk_key else 'None'}")
            
            if self.grpc_client:
                logger('warning', "[LESCOPR] Connexion gRPC déjà active")
                return True
            
            logger('info', "[LESCOPR] ==> Création du client gRPC...")
            
            from ..network.grpc.client import GrpcClient
            self.grpc_client = GrpcClient(self)
            
            logger('info', "[LESCOPR] ==> Client gRPC créé, tentative d'initialisation...")
            
            result = self.grpc_client.initialize(host, port)
            logger('info', f"[LESCOPR] ==> Résultat initialize(): {result}")
            
            if not result:
                logger('error', "[LESCOPR] ❌ Échec d'initialisation du client gRPC")
                self.grpc_client = None
                return False
            
            logger('info', "[LESCOPR] ✅ Connexion gRPC établie avec succès")
            return True
            
        except Exception as e:
            logger('error', f"[LESCOPR] ❌ Erreur gRPC: {e}")
            import traceback
            logger('error', f"[LESCOPR] Traceback complet: {traceback.format_exc()}")
            self.grpc_client = None
            return False
    
    def attach_to_daemon(self) -> bool:
        """S'attache au daemon existant SANS créer de nouvelle connexion gRPC"""
        try:
            logger('info', "[LESCOPR] Tentative d'attachement au daemon existant...")
            
            from ..network.grpc.client import GrpcClient
            self.grpc_client = GrpcClient(
                lescopr_client=self,
                auto_connect=False,  # ✅ PAS D'AUTO-CONNEXION
                daemon_mode=True     # ✅ MODE DAEMON
            )
            
            # ✅ ATTACHEMENT VIA SOCKET/FILE
            if self.grpc_client.connection and self.grpc_client.connection.daemon_mode:
                logger('debug', "[LESCOPR] Test connexion daemon...")
                
                # ✅ VRAIE CONNEXION DAEMON
                success = self.grpc_client.connection.connect()
                
                if success:
                    logger('info', "[LESCOPR] ✅ Attaché au daemon via socket/file")
                    
                    # ✅ MARQUER COMME CONNECTÉ
                    self.grpc_client._connected_simulation = True
                    
                    # ✅ INITIALISER LES HANDLERS DAEMON
                    self.grpc_client._initialize_daemon_handlers()
                    
                    logger('info', "[LESCOPR] ✅ Handlers daemon initialisés")
                    return True
                else:
                    logger('warning', "[LESCOPR] ❌ Daemon non accessible")
                    self.grpc_client = None
                    return False
            else:
                logger('error', "[LESCOPR] ❌ Erreur configuration mode daemon")
                self.grpc_client = None
                return False
                
        except Exception as e:
            logger('error', f"[LESCOPR] Erreur attachement daemon: {e}")
            import traceback
            logger('error', f"[LESCOPR] Traceback: {traceback.format_exc()}")
            self.grpc_client = None
            return False

    def send_log(self, level, message, metadata=None):
        """
        ✅ POINT D'ENTRÉE UNIFIÉ POUR TOUS LES LOGS
        
        Délègue intelligemment selon la disponibilité :
        1. gRPC connecté → Délègue au GrpcClient (qui choisit handler approprié)
        2. Pas de gRPC → Queue centrale pour envoi ultérieur
        """
        if self.grpc_client and self.grpc_client.is_connected():
            # ✅ DÉLÉGUER AU GRPC_CLIENT (proxy intelligent)
            return self.grpc_client.send_log(level, message, metadata)
        else:
            # ✅ FALLBACK : Queue centrale
            log_entry = {
                'level': level,
                'message': message,
                'metadata': metadata or {},
                'timestamp': time.time()
            }
            self.add_pending_log(log_entry)
            return False

    def add_pending_log(self, log_data: dict):
        """
        ✅ SEULE QUEUE CENTRALE DU SYSTÈME
        
        Utilisée par :
        - Fallback de send_log()
        - LescoprHandler (Python logging)
        - LogHandler (mode gRPC normal)
        
        Args:
            log_data: Dictionnaire contenant les données du log
        """
        try:
            with self._logs_lock:
                self._pending_logs_for_server.append(log_data)
                
                if len(self._pending_logs_for_server) > 1000:
                    self._pending_logs_for_server = self._pending_logs_for_server[-500:]
                    logger('warning', "[LESCOPR] Queue logs pleine - anciens logs supprimés")
                    
        except Exception as e:
            logger('error', f"[LESCOPR] Erreur ajout log pending: {e}")
    
    def get_pending_logs(self) -> list:
        """
        Récupère et vide la queue des logs en attente
        
        Returns:
            list: Liste des logs en attente (queue vidée automatiquement)
        """
        try:
            with self._logs_lock:
                if not self._pending_logs_for_server:
                    return []
                
                # ✅ COPIER ET VIDER ATOMIQUEMENT
                logs = self._pending_logs_for_server.copy()
                self._pending_logs_for_server.clear()
                
                logger('debug', f"[LESCOPR] {len(logs)} logs récupérés depuis la queue")
                return logs
                
        except Exception as e:
            logger('error', f"[LESCOPR] Erreur récupération logs pending: {e}")
            return []
    
    def has_pending_logs(self) -> bool:
        """
        Vérifie s'il y a des logs en attente de transmission
        
        Returns:
            bool: True si des logs sont en attente
        """
        try:
            with self._logs_lock:
                return len(self._pending_logs_for_server) > 0
        except Exception:
            return False
    
    def get_pending_logs_count(self) -> int:
        """
        Retourne le nombre de logs en attente
        
        Returns:
            int: Nombre de logs dans la queue
        """
        try:
            with self._logs_lock:
                return len(self._pending_logs_for_server)
        except Exception:
            return 0

    def send_metric(self, name, value, labels=None):
        if self.grpc_client and self.grpc_client.is_connected():
            self.grpc_client.send_metric(name, value, labels)

    def __del__(self):
        try:
            if hasattr(sys, 'meta_path') and sys.meta_path is not None:
                if hasattr(self, 'grpc_client') and self.grpc_client:
                    self.grpc_client.disconnect()
        except (ImportError, AttributeError):
            pass

    # ✅ MÉTHODES CLASSE INCHANGÉES (déjà clean)
    @classmethod
    def initialize_project(cls, api_key: str, sdk_key: str, environment: str = 'development') -> dict:
        """Initialise un projet Lescopr - MÉTHODE CLASSE (pas d'instance)"""
        try:
            instance = cls(
                api_key=api_key,
                sdk_key=sdk_key,
                environment=environment,
                auto_logging=False,
                auto_grpc=False
            )
            
            config = instance.initialize()
            del instance
            
            return {
                'success': True,
                'config': config,
                'error': None
            }
            
        except Exception as e:
            return {
                'success': False,
                'config': None,
                'error': str(e)
            }
    
    @classmethod
    def start_daemon(cls) -> dict:
        """Démarre le daemon en arrière-plan"""
        try:
            import subprocess
            import sys
            import os
            import time
            
            files = cls._get_project_files()
            
            # Vérifier daemon existant
            if os.path.exists(files['pid']):
                with open(files['pid'], "r") as f:
                    pid = f.read().strip()
                try:
                    os.kill(int(pid), 0)
                    return {
                        'success': False,
                        'error': f"Daemon déjà actif (PID: {pid})"
                    }
                except OSError:
                    os.unlink(files['pid'])
            
            env = {
                **os.environ,
                "LESCOPR_CONFIG_PATH": files['config'],
                "LESCOPR_LOG_LEVEL": "info",
                "LESCOPR_DAEMON_MODE": "true"
            }

            with open(files['log'], "a") as log_out:
                cmd = [sys.executable, "-m", "lescopr.daemon"]
                process = subprocess.Popen(
                    cmd,
                    stdout=log_out,
                    stderr=log_out,
                    env=env,
                    start_new_session=True,
                    cwd=os.getcwd(),
                    stdin=subprocess.DEVNULL
                )
                
                time.sleep(2)
                if process.poll() is not None:
                    return {
                        'success': False,
                        'error': "Daemon s'est arrêté immédiatement"
                    }
                
                # Sauvegarder PID
                with open(files['pid'], "w") as f:
                    f.write(str(process.pid))
                
                return {
                    'success': True,
                    'pid': process.pid,
                    'log_file': files['log'],
                    'error': None
                }
                
        except Exception as e:
            return {
                'success': False,
                'error': f"Erreur démarrage daemon: {e}"
            }
    
    @classmethod
    def stop_daemon(cls) -> dict:
        """Arrête le daemon"""
        try:
            import signal
            import time
            
            files = cls._get_project_files()
            
            if not os.path.exists(files['pid']):
                return {
                    'success': False,
                    'error': "Aucun daemon en cours d'exécution"
                }
            
            with open(files['pid'], "r") as f:
                pid = int(f.read().strip())
            
            # Arrêt gracieux
            os.kill(pid, signal.SIGTERM)
            
            # Attendre arrêt
            for i in range(5):
                try:
                    os.kill(pid, 0)
                    time.sleep(1)
                except OSError:
                    break
            else:
                # Force kill
                try:
                    os.kill(pid, signal.SIGKILL)
                except OSError:
                    pass
            
            # Nettoyer PID
            os.unlink(files['pid'])
            
            return {
                'success': True,
                'error': None
            }
            
        except Exception as e:
            return {
                'success': False,
                'error': f"Erreur arrêt daemon: {e}"
            }
    
    @classmethod
    def start_interactive(cls) -> dict:
        """Démarre en mode interactif"""
        try:
            # Charger config
            config = cls._load_project_config()
            if not config:
                return {
                    'success': False,
                    'error': "Configuration non trouvée"
                }
            
            # Créer instance avec connexion
            instance = cls(
                api_key=config.get("api_key"),
                sdk_key=config.get("sdk_key"),
                environment=config.get("environment", "development"),
                auto_logging=False,
                auto_grpc=False
            )
            
            instance.sdk_id = config.get("sdk_id")
            instance.project_name = config.get("project_name")
            
            # Démarrer connexion
            success = instance.start_grpc_streaming()
            if not success:
                return {
                    'success': False,
                    'error': "Échec connexion gRPC"
                }
            
            # Fonction d'attente
            def wait_function():
                import time
                try:
                    while True:
                        time.sleep(1)
                except KeyboardInterrupt:
                    pass
            
            # Stocker instance pour nettoyage
            cls._interactive_instance = instance
            
            return {
                'success': True,
                'wait_function': wait_function,
                'error': None
            }
            
        except Exception as e:
            return {
                'success': False,
                'error': f"Erreur mode interactif: {e}"
            }
    
    @classmethod
    def stop_interactive(cls):
        """Arrête le mode interactif"""
        if hasattr(cls, '_interactive_instance'):
            try:
                cls._interactive_instance.disconnect()
                del cls._interactive_instance
            except:
                pass
    
    @classmethod
    def get_status(cls) -> dict:
        """Retourne l'état complet du projet"""
        files = cls._get_project_files()
        config = cls._load_project_config()
        
        daemon_running = False
        daemon_pid = None
        
        if os.path.exists(files['pid']):
            try:
                with open(files['pid'], "r") as f:
                    pid = f.read().strip()
                os.kill(int(pid), 0)
                daemon_running = True
                daemon_pid = pid
            except OSError:
                pass
        
        return {
            'project_path': os.getcwd(),
            'config_file': files['config'],
            'config_exists': os.path.exists(files['config']),
            'config': config or {},
            'daemon_running': daemon_running,
            'daemon_pid': daemon_pid,
            'log_file': files['log']
        }
    
    @staticmethod
    def _get_project_files() -> dict:
        """Retourne les chemins des fichiers du projet"""
        project_root = os.getcwd()
        return {
            'config': os.path.join(project_root, ".lescopr.json"),
            'log': os.path.join(project_root, ".lescopr.log"),
            'pid': os.path.join(project_root, ".lescopr.pid")
        }
    
    @classmethod
    def _load_project_config(cls) -> dict:
        """Charge la configuration du projet"""
        try:
            files = cls._get_project_files()
            if not os.path.exists(files['config']):
                return {}
            
            with open(files['config'], "r") as f:
                return json.load(f)
        except:
            return {}

    @classmethod
    def reset_project(cls, keep_config: bool = False) -> dict:
        """Réinitialise complètement le projet Lescopr"""
        try:
            import signal
            import time
            import glob
            import subprocess
            import shutil
            
            files = cls._get_project_files()
            result = {
                'success': True,
                'error': None,
                'daemon_stopped': False,
                'config_removed': False,
                'logs_cleaned': False,
                'processes_cleaned': False
            }
            
            # 1. Arrêter le daemon proprement
            if os.path.exists(files['pid']):
                try:
                    with open(files['pid'], "r") as f:
                        pid = int(f.read().strip())
                    
                    # Arrêt gracieux
                    os.kill(pid, signal.SIGTERM)
                    
                    # Attendre l'arrêt
                    for i in range(5):
                        try:
                            os.kill(pid, 0)
                            time.sleep(1)
                        except OSError:
                            break
                    else:
                        # Force kill si nécessaire
                        try:
                            os.kill(pid, signal.SIGKILL)
                            time.sleep(1)
                        except OSError:
                            pass
                    
                    result['daemon_stopped'] = True
                    
                except (ValueError, OSError, FileNotFoundError):
                    pass
                
                # Nettoyer le fichier PID
                try:
                    os.unlink(files['pid'])
                except:
                    pass
            
            # 2. Nettoyer les processus orphelins
            try:
                # Rechercher processus lescopr (si pgrep disponible)
                try:
                    output = subprocess.check_output(
                        ['pgrep', '-f', 'lescopr.daemon'], 
                        stderr=subprocess.DEVNULL
                    ).decode().strip()
                    
                    if output:
                        pids = output.split('\n')
                        for pid in pids:
                            try:
                                os.kill(int(pid), signal.SIGTERM)
                                time.sleep(0.5)
                                try:
                                    os.kill(int(pid), 0)  # Test si toujours vivant
                                    os.kill(int(pid), signal.SIGKILL)  # Force kill
                                except OSError:
                                    pass  # Déjà mort
                            except (ValueError, OSError):
                                pass
                        result['processes_cleaned'] = True
                        
                except (subprocess.CalledProcessError, FileNotFoundError):
                    pass  # pgrep non disponible ou aucun processus trouvé
                    
            except Exception:
                pass
            
            # 3. Supprimer la configuration (sauf si keep_config)
            if not keep_config and os.path.exists(files['config']):
                try:
                    os.unlink(files['config'])
                    result['config_removed'] = True
                except Exception as e:
                    result['success'] = False
                    result['error'] = f"Erreur suppression config: {e}"
                    return result
            
            # 4. Nettoyer les logs
            try:
                # Fichier log principal
                if os.path.exists(files['log']):
                    os.unlink(files['log'])
                
                # Logs rotatés éventuels (.lescopr.log.1, .lescopr.log.2...)
                log_pattern = files['log'] + '*'
                for log_file in glob.glob(log_pattern):
                    try:
                        os.unlink(log_file)
                    except:
                        pass
                
                # Logs du monitoring module (si accessible)
                try:
                    from ..monitoring.logger import get_log_directory
                    log_dir = get_log_directory()
                    if hasattr(log_dir, 'exists') and log_dir.exists():
                        for log_file in log_dir.glob('lescopr*.log*'):
                            try:
                                log_file.unlink()
                            except:
                                pass
                except:
                    pass  # Module monitoring non accessible
                    
                result['logs_cleaned'] = True
                
            except Exception:
                pass  # Non critique
            
            # 5. Nettoyer les sockets Unix
            try:
                socket_paths = [
                    '/tmp/lescopr_daemon.sock',
                    '/tmp/lescopr.sock',
                    '/var/run/lescopr.sock'
                ]
                
                for socket_path in socket_paths:
                    if os.path.exists(socket_path):
                        try:
                            os.unlink(socket_path)
                        except:
                            pass
                            
            except Exception:
                pass
            
            # 6. Nettoyer les caches Python (optionnel)
            try:
                cache_dirs = [
                    '__pycache__',
                    '.pytest_cache', 
                    '.mypy_cache'
                ]
                
                for cache_dir in cache_dirs:
                    if os.path.exists(cache_dir):
                        try:
                            shutil.rmtree(cache_dir)
                        except:
                            pass
                            
            except Exception:
                pass
            
            return result
            
        except Exception as e:
            return {
                'success': False,
                'error': f"Erreur réinitialisation: {e}",
                'daemon_stopped': False,
                'config_removed': False,
                'logs_cleaned': False,
                'processes_cleaned': False
            }

    @classmethod
    def disconnect(cls):
        """Méthode pour déconnecter proprement (alias pour compatibilité)"""
        if hasattr(cls, '_interactive_instance'):
            try:
                if hasattr(cls._interactive_instance, 'grpc_client') and cls._interactive_instance.grpc_client:
                    cls._interactive_instance.grpc_client.disconnect()
                del cls._interactive_instance
            except:
                pass