"""
Tests pour les modèles SQLAlchemy
"""
import pytest
from datetime import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from backend.app.core.database import Base
from backend.app.models.ip import IP, IPHistory


class TestSQLAlchemyModels:
    """Tests pour les modèles de données"""

    @pytest.fixture
    def db_session(self):
        """Fixture session DB en mémoire"""
        # Créer une DB SQLite en mémoire
        engine = create_engine("sqlite:///:memory:")
        Base.metadata.create_all(engine)

        Session = sessionmaker(bind=engine)
        session = Session()

        yield session

        session.close()

    def test_create_ip(self, db_session):
        """Test création d'une IP"""
        ip = IP(
            ip="192.168.1.100",
            name="Test Server",
            known=True,
            location="Bureau",
            host="Serveur",
            last_status="online",
            mac="00:11:22:33:44:55",
            vendor="Dell",
            open_ports=[22, 80, 443]
        )

        db_session.add(ip)
        db_session.commit()

        # Vérifier la création
        retrieved = db_session.query(IP).filter(IP.ip == "192.168.1.100").first()
        assert retrieved is not None
        assert retrieved.name == "Test Server"
        assert retrieved.known is True
        assert retrieved.last_status == "online"
        assert len(retrieved.open_ports) == 3

    def test_create_ip_history(self, db_session):
        """Test création d'historique IP"""
        # Créer d'abord une IP
        ip = IP(
            ip="192.168.1.101",
            last_status="online"
        )
        db_session.add(ip)
        db_session.commit()

        # Créer entrée historique
        history = IPHistory(
            ip="192.168.1.101",
            timestamp=datetime.now(),
            status="online",
            open_ports=[80, 443]
        )

        db_session.add(history)
        db_session.commit()

        # Vérifier
        retrieved = db_session.query(IPHistory).filter(
            IPHistory.ip == "192.168.1.101"
        ).first()

        assert retrieved is not None
        assert retrieved.status == "online"
        assert len(retrieved.open_ports) == 2

    def test_ip_history_relationship(self, db_session):
        """Test relation IP <-> IPHistory"""
        # Créer une IP
        ip = IP(
            ip="192.168.1.102",
            last_status="online"
        )
        db_session.add(ip)
        db_session.commit()

        # Créer plusieurs entrées historiques
        for i in range(5):
            history = IPHistory(
                ip="192.168.1.102",
                status="online" if i % 2 == 0 else "offline",
                open_ports=[]
            )
            db_session.add(history)

        db_session.commit()

        # Vérifier la relation
        ip = db_session.query(IP).filter(IP.ip == "192.168.1.102").first()
        assert len(ip.history) == 5

    def test_cascade_delete(self, db_session):
        """Test suppression en cascade"""
        # Créer IP + historique
        ip = IP(ip="192.168.1.103", last_status="online")
        db_session.add(ip)
        db_session.commit()

        history = IPHistory(
            ip="192.168.1.103",
            status="online",
            open_ports=[]
        )
        db_session.add(history)
        db_session.commit()

        # Supprimer l'IP
        db_session.delete(ip)
        db_session.commit()

        # Vérifier que l'historique est supprimé aussi
        history_count = db_session.query(IPHistory).filter(
            IPHistory.ip == "192.168.1.103"
        ).count()

        assert history_count == 0
