"""
Tests pour les nouveaux thèmes GUI
"""

import unittest
import tempfile
import json
import os
from pathlib import Path

from web_sentinel.gui.themes_gui.shared import DataManager, get_data_manager, ScanController


class TestDataManager(unittest.TestCase):
    """Tests pour DataManager."""
    
    def setUp(self):
        """Configuration avant chaque test."""
        # Sauvegarder et effacer les variables d'environnement
        self.saved_env = {}
        env_vars = ["WS_GUI_THEME", "WS_LANGUAGE", "WS_DOMAINS", "WS_TIMEOUT", 
                    "WS_ALLOW_INVASIVE", "WS_MODULES", "WS_API_URL", 
                    "WS_STRIPE_PUBLIC_KEY", "WS_HISTORY_ENABLED"]
        
        for var in env_vars:
            if var in os.environ:
                self.saved_env[var] = os.environ[var]
                del os.environ[var]
        
        # Utiliser le singleton
        self.dm = get_data_manager()
        # Reset avant chaque test
        self.dm.reset()
    
    def test_gui_theme_default(self):
        """Test de la valeur par défaut du thème."""
        self.assertEqual(self.dm.get_gui_theme(), "classic")
    
    def test_gui_theme_set_get(self):
        """Test set/get du thème."""
        self.dm.set_gui_theme("dark")
        self.assertEqual(self.dm.get_gui_theme(), "dark")
    
    def test_language_default(self):
        """Test de la langue par défaut."""
        self.assertEqual(self.dm.get_language(), "fr")
    
    def test_language_set_get(self):
        """Test set/get de la langue."""
        self.dm.set_language("en")
        self.assertEqual(self.dm.get_language(), "en")
    
    def test_domains_empty(self):
        """Test liste de domaines vide."""
        self.assertEqual(self.dm.get_domains(), [])
    
    def test_domains_set_get(self):
        """Test set/get des domaines."""
        domains = ["example.com", "test.org"]
        self.dm.set_domains(domains)
        self.assertEqual(self.dm.get_domains(), domains)
    
    def test_domains_add(self):
        """Test ajout d'un domaine."""
        self.dm.set_domains(["example.com"])
        self.dm.add_domain("test.org")
        self.assertEqual(self.dm.get_domains(), ["example.com", "test.org"])
    
    def test_timeout_default(self):
        """Test timeout par défaut."""
        self.assertEqual(self.dm.get_timeout(), 5.0)
    
    def test_timeout_set_get(self):
        """Test set/get du timeout."""
        self.dm.set_timeout(10.0)
        self.assertEqual(self.dm.get_timeout(), 10.0)
    
    def test_allow_invasive_default(self):
        """Test mode invasif par défaut."""
        self.assertEqual(self.dm.get_allow_invasive(), False)
    
    def test_allow_invasive_set_get(self):
        """Test set/get du mode invasif."""
        self.dm.set_allow_invasive(True)
        self.assertEqual(self.dm.get_allow_invasive(), True)
    
    def test_history_enabled_default(self):
        """Test historique par défaut."""
        self.assertEqual(self.dm.get_history_enabled(), True)
    
    def test_history_enabled_set_get(self):
        """Test set/get de l'historique."""
        self.dm.set_history_enabled(False)
        self.assertEqual(self.dm.get_history_enabled(), False)
    
    def test_api_url_default(self):
        """Test URL API par défaut."""
        self.assertEqual(self.dm.get_api_url(), "http://localhost:5000")
    
    def test_window_geometry_none(self):
        """Test géométrie fenêtre par défaut."""
        self.assertIsNone(self.dm.get_window_geometry())
    
    def test_window_geometry_set_get(self):
        """Test set/get de la géométrie."""
        geometry = "1200x800+100+100"
        self.dm.set_window_geometry(geometry)
        self.assertEqual(self.dm.get_window_geometry(), geometry)
    
    def test_generic_get_set(self):
        """Test méthodes génériques get/set."""
        self.dm.set("custom_key", "custom_value")
        self.assertEqual(self.dm.get("custom_key"), "custom_value")
    
    def test_persistence(self):
        """Test de la persistance des données."""
        # Définir des valeurs
        self.dm.set_gui_theme("cyberpunk")
        self.dm.set_language("en")
        self.dm.set_domains(["example.com"])
        self.dm.set_timeout(15.0)
        
        # Sauvegarder
        self.dm.save_config()
        
        # Créer un nouveau DataManager
        dm2 = DataManager()
        
        # Vérifier que les valeurs sont persistées
        self.assertEqual(dm2.get_gui_theme(), "cyberpunk")
        self.assertEqual(dm2.get_language(), "en")
        self.assertEqual(dm2.get_domains(), ["example.com"])
        self.assertEqual(dm2.get_timeout(), 15.0)
    
    def test_reset(self):
        """Test du reset de la configuration."""
        self.dm.set_gui_theme("minimal")
        self.dm.set_language("en")
        self.dm.reset()
        
        # Vérifier que les valeurs par défaut sont restaurées
        self.assertEqual(self.dm.get_gui_theme(), "classic")
        self.assertEqual(self.dm.get_language(), "fr")
    
    def tearDown(self):
        """Nettoyage après chaque test."""
        # Reset après chaque test
        self.dm.reset()
        
        # Restaurer les variables d'environnement
        for var, value in self.saved_env.items():
            os.environ[var] = value


class TestScanController(unittest.TestCase):
    """Tests pour ScanController."""
    
    def setUp(self):
        """Configuration avant chaque test."""
        self.controller = ScanController()
    
    def test_initial_state(self):
        """Test de l'état initial."""
        self.assertFalse(self.controller.is_scanning)
        self.assertIsNone(self.controller.current_thread)
        self.assertEqual(self.controller.scan_results, [])
    
    def test_callbacks_none(self):
        """Test que les callbacks sont None par défaut."""
        self.assertIsNone(self.controller.on_scan_start)
        self.assertIsNone(self.controller.on_scan_progress)
        self.assertIsNone(self.controller.on_scan_complete)
        self.assertIsNone(self.controller.on_scan_error)
    
    def test_callbacks_assignment(self):
        """Test de l'assignation des callbacks."""
        def dummy_callback():
            pass
        
        self.controller.on_scan_start = dummy_callback
        self.assertEqual(self.controller.on_scan_start, dummy_callback)
    
    def test_get_last_results_empty(self):
        """Test get_last_results sans résultats."""
        self.assertEqual(self.controller.get_last_results(), [])
    
    def test_scanner_instance(self):
        """Test que le scanner est instancié."""
        self.assertIsNotNone(self.controller.scanner)
    
    def test_history_store_instance(self):
        """Test que l'historique est instancié."""
        self.assertIsNotNone(self.controller.history_store)


class TestThemeImports(unittest.TestCase):
    """Tests d'import des composants shared (DataManager, ScanController)."""
    
    # Note: Les tests d'import des GUI thématiques ont été supprimés
    # car ces fichiers n'existent plus (remplacés par ThemeApplicator)
    
    def test_import_base_window(self):
        """Test import BaseWindow."""
        from web_sentinel.gui.themes_gui.shared import BaseWindow
        self.assertIsNotNone(BaseWindow)
    
    def test_import_data_manager(self):
        """Test import DataManager."""
        from web_sentinel.gui.themes_gui.shared import DataManager
        self.assertIsNotNone(DataManager)
    
    def test_import_scan_controller(self):
        """Test import ScanController."""
        from web_sentinel.gui.themes_gui.shared import ScanController
        self.assertIsNotNone(ScanController)
    
    def test_get_data_manager_singleton(self):
        """Test que get_data_manager retourne toujours la même instance."""
        from web_sentinel.gui.themes_gui.shared import get_data_manager
        
        dm1 = get_data_manager()
        dm2 = get_data_manager()
        
        self.assertIs(dm1, dm2)


def run_tests():
    """Lance tous les tests."""
    loader = unittest.TestLoader()
    suite = unittest.TestSuite()
    
    # Ajouter tous les tests
    suite.addTests(loader.loadTestsFromTestCase(TestDataManager))
    suite.addTests(loader.loadTestsFromTestCase(TestScanController))
    suite.addTests(loader.loadTestsFromTestCase(TestThemeImports))
    
    # Lancer les tests
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(suite)
    
    # Résumé
    print("\n" + "="*70)
    print("RÉSUMÉ DES TESTS")
    print("="*70)
    print(f"Tests exécutés : {result.testsRun}")
    print(f"Succès         : {result.testsRun - len(result.failures) - len(result.errors)}")
    print(f"Échecs         : {len(result.failures)}")
    print(f"Erreurs        : {len(result.errors)}")
    print("="*70)
    
    return result.wasSuccessful()


if __name__ == "__main__":
    success = run_tests()
    exit(0 if success else 1)
