"""Shared test fixtures and markers."""

from __future__ import annotations

from typing import Any

import httpx
import pytest


@pytest.fixture
def mock_pdp_allow() -> httpx.Client:
    """httpx.Client that returns an AuthZEN allow decision."""
    return httpx.Client(
        transport=httpx.MockTransport(_make_pdp_handler(decision=True)),
    )


@pytest.fixture
def mock_pdp_deny() -> httpx.Client:
    """httpx.Client that returns an AuthZEN deny decision."""
    return httpx.Client(
        transport=httpx.MockTransport(_make_pdp_handler(decision=False)),
    )


@pytest.fixture
def mock_pdp_deny_with_constraints() -> httpx.Client:
    """httpx.Client that denies with constraints for parameter clamping."""
    return httpx.Client(
        transport=httpx.MockTransport(
            _make_pdp_handler(
                decision=False,
                context={
                    "reason_admin": "max_rows exceeded",
                    "constraints": {"max_rows": 100},
                },
            )
        ),
    )


@pytest.fixture
def mock_pdp_error() -> httpx.Client:
    """httpx.Client that simulates a PDP server error."""

    def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(status_code=503, text="Service Unavailable")

    return httpx.Client(transport=httpx.MockTransport(handler))


@pytest.fixture
def mock_receipt_vault() -> httpx.Client:
    """httpx.Client that accepts receipt vault POST requests."""

    def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(status_code=201, json={"status": "ok"})

    return httpx.Client(transport=httpx.MockTransport(handler))


@pytest.fixture
def mock_receipt_vault_error() -> httpx.Client:
    """httpx.Client that always fails for receipt vault."""

    def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(status_code=500, text="Internal Server Error")

    return httpx.Client(transport=httpx.MockTransport(handler))


@pytest.fixture
def mock_pdp_policies() -> httpx.Client:
    """httpx.Client that returns a list of policies."""

    def handler(request: httpx.Request) -> httpx.Response:
        policies = {
            "policies": [
                {
                    "id": "pol-001",
                    "name": "tool-access",
                    "description": "Controls tool access",
                    "rules": [{"action_type": "tool.invoke", "effect": "allow"}],
                    "priority": 10,
                    "enabled": True,
                },
                {
                    "id": "pol-002",
                    "name": "read-only",
                    "description": "Read-only policy",
                    "rules": [{"action_type": "data.read", "effect": "allow"}],
                    "priority": 5,
                    "enabled": True,
                },
            ]
        }
        return httpx.Response(status_code=200, json=policies)

    return httpx.Client(transport=httpx.MockTransport(handler))


def _make_pdp_handler(
    decision: bool,
    context: dict[str, Any] | None = None,
) -> Any:
    """Create a mock PDP handler returning a fixed AuthZEN response."""

    def handler(request: httpx.Request) -> httpx.Response:
        body: dict[str, Any] = {"decision": decision}
        if context is not None:
            body["context"] = context
        return httpx.Response(status_code=200, json=body)

    return handler
