"""Tests for the ECP authentication backend."""

from __future__ import annotations

from typing import Any

import pytest
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import rsa

from ecp_auth.backends import ECPAuthenticationBackend
from ecp_auth.crypto import Challenge, generate_challenge, sign_data, encode_signature_b64
from ecp_auth.models import UserCertificate
from ecp_auth.parsers import extract_certificate_info


@pytest.mark.django_db
class TestECPAuthenticationBackend:
    """Tests for the ECPAuthenticationBackend."""

    def _register_cert(
        self, user: Any, certificate: x509.Certificate
    ) -> UserCertificate:
        """Helper to register a certificate for a user."""
        info = extract_certificate_info(certificate)
        return UserCertificate.objects.create(
            user=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,
        )

    def test_authenticate_success(
        self,
        test_user: Any,
        rsa_private_key: rsa.RSAPrivateKey,
        self_signed_certificate: x509.Certificate,
    ) -> None:
        """Test successful authentication."""
        self._register_cert(test_user, self_signed_certificate)

        challenge = generate_challenge()
        signature = sign_data(rsa_private_key, challenge.nonce_bytes)
        signature_b64 = encode_signature_b64(signature)

        backend = ECPAuthenticationBackend()
        user = backend.authenticate(
            request=None,
            certificate=self_signed_certificate,
            signature=signature_b64,
            challenge=challenge,
        )

        assert user is not None
        assert user.username == "testuser"

    def test_authenticate_no_certificate(self) -> None:
        """Test that missing certificate returns None."""
        backend = ECPAuthenticationBackend()
        result = backend.authenticate(request=None)

        assert result is None

    def test_authenticate_unregistered_cert(
        self,
        rsa_private_key: rsa.RSAPrivateKey,
        self_signed_certificate: x509.Certificate,
    ) -> None:
        """Test that unregistered certificate returns None."""
        challenge = generate_challenge()
        signature = sign_data(rsa_private_key, challenge.nonce_bytes)
        signature_b64 = encode_signature_b64(signature)

        backend = ECPAuthenticationBackend()
        user = backend.authenticate(
            request=None,
            certificate=self_signed_certificate,
            signature=signature_b64,
            challenge=challenge,
        )

        assert user is None

    def test_get_user(self, test_user: Any) -> None:
        """Test retrieving user by ID."""
        backend = ECPAuthenticationBackend()
        user = backend.get_user(test_user.pk)

        assert user is not None
        assert user.pk == test_user.pk

    def test_get_user_not_found(self) -> None:
        """Test that non-existent user ID returns None."""
        backend = ECPAuthenticationBackend()
        user = backend.get_user(999999)

        assert user is None
