"""AP001: Public endpoint without explicit intent."""

from collections.abc import Iterator

from apiposture.core.models.endpoint import Endpoint
from apiposture.core.models.enums import SecurityClassification, Severity
from apiposture.core.models.finding import Finding
from apiposture.rules.base import SecurityRule


class AP001PublicWithoutIntent(SecurityRule):
    """
    AP001: Public endpoint without explicit intent.

    Triggers when an endpoint is public (no authentication) but doesn't have
    an explicit marker indicating this is intentional (e.g., AllowAny, AllowAnonymous).
    """

    @property
    def rule_id(self) -> str:
        return "AP001"

    @property
    def name(self) -> str:
        return "Public without explicit intent"

    @property
    def severity(self) -> Severity:
        return Severity.HIGH

    @property
    def description(self) -> str:
        return (
            "Public endpoint without explicit authorization intent. "
            "Endpoints should explicitly declare their authorization requirements."
        )

    def evaluate(self, endpoint: Endpoint) -> Iterator[Finding]:
        """Check if endpoint is public without explicit AllowAnonymous/AllowAny."""
        if endpoint.classification != SecurityClassification.PUBLIC:
            return

        auth = endpoint.authorization

        # If explicitly marked as anonymous/public, this is intentional
        if auth.allows_anonymous:
            return

        # If there's any auth configuration at all, skip
        if auth.requires_auth or auth.auth_dependencies or auth.has_specific_requirements:
            return

        yield self.create_finding(
            endpoint,
            message=(
                f"Endpoint '{endpoint.full_route}' is public without "
                "explicit authorization intent"
            ),
            recommendation=(
                "Add explicit authorization: use AllowAny (DRF), "
                "or document why no authentication is needed"
            ),
        )
