import pytest
from fastapi import HTTPException

from bluefox_auth.csrf import validate_csrf

COOKIE_NAME = "bf_csrf_token"


class FakeRequest:
    def __init__(self, method: str, cookies: dict | None = None, headers: dict | None = None):
        self.method = method
        self.cookies = cookies or {}
        self.headers = headers or {}


def test_csrf__skips_safe_methods():
    for method in ["GET", "HEAD", "OPTIONS"]:
        request = FakeRequest(method=method)
        validate_csrf(request, COOKIE_NAME)  # should not raise


def test_csrf__skips_bearer_auth():
    request = FakeRequest(
        method="POST",
        headers={"Authorization": "Bearer some-token"},
    )
    validate_csrf(request, COOKIE_NAME)  # should not raise


def test_csrf__rejects_missing_header():
    request = FakeRequest(
        method="POST",
        cookies={COOKIE_NAME: "token-value"},
    )
    with pytest.raises(HTTPException) as exc_info:
        validate_csrf(request, COOKIE_NAME)
    assert exc_info.value.status_code == 403


def test_csrf__rejects_missing_cookie():
    request = FakeRequest(
        method="POST",
        headers={"X-CSRF-Token": "token-value"},
    )
    with pytest.raises(HTTPException) as exc_info:
        validate_csrf(request, COOKIE_NAME)
    assert exc_info.value.status_code == 403


def test_csrf__rejects_mismatch():
    request = FakeRequest(
        method="POST",
        cookies={COOKIE_NAME: "cookie-token"},
        headers={"X-CSRF-Token": "different-token"},
    )
    with pytest.raises(HTTPException) as exc_info:
        validate_csrf(request, COOKIE_NAME)
    assert exc_info.value.status_code == 403


def test_csrf__accepts_matching_tokens():
    token = "matching-csrf-token"
    request = FakeRequest(
        method="POST",
        cookies={COOKIE_NAME: token},
        headers={"X-CSRF-Token": token},
    )
    validate_csrf(request, COOKIE_NAME)  # should not raise
