"""Tests for the ECP views."""

from __future__ import annotations

from typing import Any

import pytest
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import rsa
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client, TestCase

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


@pytest.mark.django_db
class TestECPLoginView:
    """Tests for the login view."""

    def test_login_page_get(self) -> None:
        """Test GET request renders login page."""
        client = Client()
        response = client.get("/auth/login/")

        assert response.status_code == 200
        assert b"Sign In" in response.content or b"Authenticate" in response.content

    def test_login_upload_valid_cert(
        self,
        test_user: Any,
        pkcs12_data: bytes,
        self_signed_certificate: x509.Certificate,
    ) -> None:
        """Test uploading a valid registered certificate."""
        # Register the certificate first
        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,
            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,
        )

        client = Client()
        uploaded_file = SimpleUploadedFile(
            "test.p12", pkcs12_data, content_type="application/x-pkcs12"
        )

        response = client.post(
            "/auth/login/",
            {
                "step": "upload",
                "pkcs12_file": uploaded_file,
                "pkcs12_password": "testpassword",
            },
        )

        assert response.status_code == 200
        # Should show challenge step
        assert b"challenge" in response.content.lower() or b"Confirm" in response.content

    def test_login_upload_unregistered_cert(
        self, pkcs12_data: bytes
    ) -> None:
        """Test uploading an unregistered certificate."""
        client = Client()
        uploaded_file = SimpleUploadedFile(
            "test.p12", pkcs12_data, content_type="application/x-pkcs12"
        )

        response = client.post(
            "/auth/login/",
            {
                "step": "upload",
                "pkcs12_file": uploaded_file,
                "pkcs12_password": "testpassword",
            },
        )

        assert response.status_code == 200
        assert b"not registered" in response.content.lower()


@pytest.mark.django_db
class TestECPRegisterView:
    """Tests for the register view."""

    def test_register_page_get(self) -> None:
        """Test GET request renders registration page."""
        client = Client()
        response = client.get("/auth/register/")

        assert response.status_code == 200
        assert b"Register" in response.content

    def test_register_success(self, pkcs12_data: bytes) -> None:
        """Test successful registration."""
        client = Client()
        uploaded_file = SimpleUploadedFile(
            "test.p12", pkcs12_data, content_type="application/x-pkcs12"
        )

        response = client.post(
            "/auth/register/",
            {
                "username": "newecpuser",
                "email": "ecp@example.com",
                "pkcs12_file": uploaded_file,
                "pkcs12_password": "testpassword",
            },
        )

        # Should redirect to login page on success
        assert response.status_code == 302

        # Check user and certificate were created
        from django.contrib.auth import get_user_model

        User = get_user_model()
        assert User.objects.filter(username="newecpuser").exists()
        assert UserCertificate.objects.filter(
            user__username="newecpuser"
        ).exists()


@pytest.mark.django_db
class TestECPLogoutView:
    """Tests for the logout view."""

    def test_logout_get(self) -> None:
        """Test logout via GET request."""
        client = Client()
        response = client.get("/auth/logout/")

        assert response.status_code == 302  # Redirect


@pytest.mark.django_db
class TestECPChallengeView:
    """Tests for the challenge API view."""

    def test_generate_challenge(self) -> None:
        """Test generating a challenge via POST."""
        client = Client()
        response = client.post(
            "/auth/challenge/",
            {"action": "generate"},
        )

        assert response.status_code == 200
        data = response.json()
        assert "nonce" in data
        assert "timeout" in data

    def test_invalid_action(self) -> None:
        """Test invalid action returns 400."""
        client = Client()
        response = client.post(
            "/auth/challenge/",
            {"action": "invalid"},
        )

        assert response.status_code == 400
