"""Base class for Pro security rules."""

import re

from apiposture.core.models.endpoint import Endpoint
from apiposture.rules.base import SecurityRule

KNOWN_PUBLIC_ROUTE_SEGMENTS: frozenset[str] = frozenset(
    {
        # --- Authentication entry points ---
        "login", "signin", "sign-in", "sign_in",
        "logout", "signout", "sign-out", "sign_out",
        "register", "signup", "sign-up", "sign_up",
        "token", "authorize", "callback", "verify", "confirm",
        "reset-password", "reset_password",
        "forgot-password", "forgot_password",
        "password-recovery", "password_recovery",
        "request-verify", "request_verify",
        "webhook",
        # --- Infrastructure / operational endpoints ---
        "health", "healthz", "health-check", "health_check",
        "ping", "alive", "ready", "readiness", "liveness",
    }
)


def is_known_public_endpoint(endpoint: Endpoint) -> bool:
    """Return True if this endpoint is a well-known intentionally public route."""
    route_lower = endpoint.full_route.lower()
    func_lower = (endpoint.function_name or "").lower()
    return any(
        segment in route_lower or segment in func_lower
        for segment in KNOWN_PUBLIC_ROUTE_SEGMENTS
    )


def _keyword_match(text: str, keyword: str) -> bool:
    """Match keyword at word boundaries (separated by _, /, -, ., or string edges)."""
    return bool(re.search(rf"(?:^|[_/\-.]){re.escape(keyword)}(?:$|[_/\-.])", text))


def _any_keyword_match(text: str, keywords: list[str]) -> bool:
    """Check if any keyword matches at word boundaries."""
    return any(_keyword_match(text, kw) for kw in keywords)


class ProSecurityRule(SecurityRule):
    """
    Base class for Pro-only security rules.

    Pro rules extend the free version's SecurityRule with additional
    capabilities and more sophisticated analysis.
    """

    @property
    def is_pro_rule(self) -> bool:
        """Identify this as a Pro rule."""
        return True
