"""
Tests de sécurité — GestionEmail
Vérifie :
  - search_recipients nécessite une authentification (plus accessible anonymement)
  - send-email nécessite une authentification
  - Les données personnelles ne sont pas dans les logs INFO
"""

import json

from django.test import TestCase, override_settings
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from rest_framework_simplejwt.tokens import RefreshToken

from Auth.models import Profile, ProfileRole
from Establishment.models import Establishment


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def create_user_with_role(email, password="TestPass!123"):
    user = Profile.objects.create_user(
        username=email, email=email, password=password
    )
    est = Establishment.objects.create(
        name=f"Ecole {email}",
        address="1 rue Test",
        total_capacity=50,
        establishment_type=[1],
    )
    ProfileRole.objects.create(
        profile=user,
        role_type=ProfileRole.RoleType.PROFIL_ECOLE,
        establishment=est,
        is_active=True,
    )
    return user, est


OVERRIDE = dict(
    CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}},
    SESSION_ENGINE='django.contrib.sessions.backends.db',
)


# ---------------------------------------------------------------------------
# Tests : search_recipients exige une authentification
# ---------------------------------------------------------------------------

@override_settings(**OVERRIDE)
class SearchRecipientsAuthTest(TestCase):
    """
    GET /email/search-recipients/ doit retourner 401 si non authentifié.
    Avant la correction, cet endpoint était accessible anonymement
    (harvesting d'emails des membres d'un établissement).
    """

    def setUp(self):
        self.client = APIClient()
        self.url = reverse('GestionEmail:search_recipients')

    def test_sans_auth_retourne_401(self):
        """Accès anonyme doit être rejeté avec 401."""
        response = self.client.get(self.url, {'q': 'test', 'establishment_id': 1})
        self.assertEqual(
            response.status_code, status.HTTP_401_UNAUTHORIZED,
            "search_recipients doit exiger une authentification (OWASP A01 - Broken Access Control)"
        )

    def test_avec_auth_et_query_vide_retourne_200_ou_liste_vide(self):
        """Un utilisateur authentifié sans terme de recherche reçoit une liste vide."""
        user, est = create_user_with_role('search_auth@test.com')
        token = str(RefreshToken.for_user(user).access_token)
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
        response = self.client.get(self.url, {'q': '', 'establishment_id': est.id})
        self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])

    def test_avec_auth_et_establishment_manquant_retourne_400(self):
        """Un utilisateur authentifié sans establishment_id reçoit 400."""
        user, _ = create_user_with_role('search_noest@test.com')
        token = str(RefreshToken.for_user(user).access_token)
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
        response = self.client.get(self.url, {'q': 'alice'})
        self.assertIn(response.status_code, [status.HTTP_400_BAD_REQUEST, status.HTTP_200_OK])


# ---------------------------------------------------------------------------
# Tests : send-email exige une authentification
# ---------------------------------------------------------------------------

@override_settings(**OVERRIDE)
class SendEmailAuthTest(TestCase):
    """
    POST /email/send-email/ doit retourner 401 si non authentifié.
    """

    def setUp(self):
        self.client = APIClient()
        self.url = reverse('GestionEmail:send_email')

    def test_sans_auth_retourne_401(self):
        """Accès anonyme à l'envoi d'email doit être rejeté."""
        payload = {
            'recipients': ['victim@example.com'],
            'subject': 'Test',
            'message': 'Hello',
            'establishment_id': 1,
        }
        response = self.client.post(
            self.url, data=json.dumps(payload), content_type='application/json'
        )
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
