"""
Tests unitaires pour les modules réseau
Basé sur tests-backend.md
"""
import pytest
import asyncio
from backend.app.services.network import NetworkScanner


class TestNetworkScanner:
    """Tests pour le scanner réseau"""

    @pytest.fixture
    def scanner(self):
        """Fixture scanner avec réseau de test"""
        return NetworkScanner(cidr="192.168.1.0/24", timeout=1.0)

    def test_generate_ip_list(self, scanner):
        """Test génération liste IP depuis CIDR"""
        ip_list = scanner.generate_ip_list()

        # Vérifier le nombre d'IPs (254 pour un /24)
        assert len(ip_list) == 254

        # Vérifier format
        assert "192.168.1.1" in ip_list
        assert "192.168.1.254" in ip_list
        assert "192.168.1.0" not in ip_list  # Adresse réseau exclue
        assert "192.168.1.255" not in ip_list  # Broadcast exclu

    @pytest.mark.asyncio
    async def test_ping(self, scanner):
        """Test fonction ping"""
        # Ping localhost (devrait marcher)
        result = await scanner.ping("127.0.0.1")
        assert result is True

        # Ping IP improbable (devrait échouer rapidement)
        result = await scanner.ping("192.0.2.1")
        assert result is False

    @pytest.mark.asyncio
    async def test_ping_parallel(self, scanner):
        """Test ping parallélisé"""
        ip_list = ["127.0.0.1", "192.0.2.1", "192.0.2.2"]

        results = await scanner.ping_parallel(ip_list, max_concurrent=10)

        # Vérifier que tous les résultats sont présents
        assert len(results) == 3
        assert "127.0.0.1" in results
        assert results["127.0.0.1"] is True

    def test_classification(self, scanner):
        """Test classification d'état IP"""
        # IP en ligne + connue
        status = scanner.classify_ip_status(is_online=True, is_known=True)
        assert status == "online"

        # IP hors ligne + connue
        status = scanner.classify_ip_status(is_online=False, is_known=True)
        assert status == "offline"

        # IP en ligne + inconnue
        status = scanner.classify_ip_status(is_online=True, is_known=False)
        assert status == "online"

        # IP hors ligne + inconnue
        status = scanner.classify_ip_status(is_online=False, is_known=False)
        assert status == "offline"

    @pytest.mark.asyncio
    async def test_port_scan(self, scanner):
        """Test scan de ports"""
        # Scanner des ports communs sur localhost
        ports = [22, 80, 443, 9999]  # 9999 probablement fermé

        open_ports = await scanner.scan_ports("127.0.0.1", ports)

        # Au moins vérifier que la fonction retourne une liste
        assert isinstance(open_ports, list)

        # Tous les ports retournés doivent être dans la liste demandée
        for port in open_ports:
            assert port in ports

    def test_get_mac_vendor(self, scanner):
        """Test lookup fabricant MAC"""
        # Tester avec des MACs connus
        vendor = scanner._get_mac_vendor("00:0C:29:XX:XX:XX")
        assert vendor == "VMware"

        vendor = scanner._get_mac_vendor("B8:27:EB:XX:XX:XX")
        assert vendor == "Raspberry Pi"

        # MAC inconnu
        vendor = scanner._get_mac_vendor("AA:BB:CC:DD:EE:FF")
        assert vendor == "Unknown"
