"""Tests for Django models."""

from __future__ import annotations

from datetime import timedelta
from typing import Any

import pytest
from cryptography import x509
from django.contrib.auth import get_user_model
from django.utils import timezone

from ecp_auth.models import UserCertificate
from ecp_auth.parsers import extract_certificate_info

User = get_user_model()


@pytest.mark.django_db
class TestUserCertificateModel:
    """Tests for the UserCertificate model."""

    def test_create_certificate(
        self, test_user: Any, self_signed_certificate: x509.Certificate
    ) -> None:
        """Test creating a UserCertificate record."""
        info = extract_certificate_info(self_signed_certificate)

        cert = UserCertificate.objects.create(
            user=test_user,
            fingerprint_sha256=info.fingerprint_sha256,
            subject_dn=info.subject_dn,
            issuer_dn=info.issuer_dn,
            serial_number=info.serial_number,
            common_name=info.common_name,
            organization=info.organization,
            not_valid_before=info.not_valid_before,
            not_valid_after=info.not_valid_after,
            certificate_pem=info.pem_data,
            is_active=True,
        )

        assert cert.pk is not None
        assert cert.user == test_user
        assert cert.fingerprint_sha256 == info.fingerprint_sha256
        assert cert.common_name == "Test User"
        assert cert.is_active is True

    def test_str_representation(
        self, test_user: Any, self_signed_certificate: x509.Certificate
    ) -> None:
        """Test string representation of UserCertificate."""
        info = extract_certificate_info(self_signed_certificate)

        cert = UserCertificate.objects.create(
            user=test_user,
            fingerprint_sha256=info.fingerprint_sha256,
            subject_dn=info.subject_dn,
            issuer_dn=info.issuer_dn,
            serial_number=info.serial_number,
            common_name=info.common_name,
            not_valid_before=info.not_valid_before,
            not_valid_after=info.not_valid_after,
            certificate_pem=info.pem_data,
        )

        assert "testuser" in str(cert)
        assert "Test User" in str(cert)

    def test_is_expired_property(self, test_user: Any) -> None:
        """Test the is_expired property."""
        cert = UserCertificate.objects.create(
            user=test_user,
            fingerprint_sha256="a" * 64,
            subject_dn="CN=Test",
            issuer_dn="CN=Test",
            serial_number="123",
            not_valid_before=timezone.now() - timedelta(days=365),
            not_valid_after=timezone.now() - timedelta(days=1),
            certificate_pem="---PEM---",
        )

        assert cert.is_expired is True

    def test_is_not_yet_valid_property(self, test_user: Any) -> None:
        """Test the is_not_yet_valid property."""
        cert = UserCertificate.objects.create(
            user=test_user,
            fingerprint_sha256="b" * 64,
            subject_dn="CN=Future",
            issuer_dn="CN=Future",
            serial_number="456",
            not_valid_before=timezone.now() + timedelta(days=1),
            not_valid_after=timezone.now() + timedelta(days=365),
            certificate_pem="---PEM---",
        )

        assert cert.is_not_yet_valid is True

    def test_unique_fingerprint(
        self, test_user: Any, self_signed_certificate: x509.Certificate
    ) -> None:
        """Test that fingerprint uniqueness is enforced."""
        from django.db import IntegrityError

        info = extract_certificate_info(self_signed_certificate)

        UserCertificate.objects.create(
            user=test_user,
            fingerprint_sha256=info.fingerprint_sha256,
            subject_dn=info.subject_dn,
            issuer_dn=info.issuer_dn,
            serial_number=info.serial_number,
            not_valid_before=info.not_valid_before,
            not_valid_after=info.not_valid_after,
            certificate_pem=info.pem_data,
        )

        with pytest.raises(IntegrityError):
            UserCertificate.objects.create(
                user=test_user,
                fingerprint_sha256=info.fingerprint_sha256,
                subject_dn=info.subject_dn,
                issuer_dn=info.issuer_dn,
                serial_number=info.serial_number,
                not_valid_before=info.not_valid_before,
                not_valid_after=info.not_valid_after,
                certificate_pem=info.pem_data,
            )
