"""Pagination validation rules."""

from __future__ import annotations

import re
from typing import Any

from hatchdx.validator.models import ValidationResult, ValidationRule
from hatchdx.validator.registry import register_rule

# Heuristics for detecting list-returning tools by name pattern.
_LIST_TOOL_PATTERNS = [
    re.compile(r"_list$"),
    re.compile(r"_list_"),
    re.compile(r"^list_"),
    re.compile(r"_search$"),
    re.compile(r"^search_"),
    re.compile(r"_query$"),
    re.compile(r"^query_"),
    re.compile(r"_get_all$"),
    re.compile(r"^get_all_"),
    re.compile(r"_find$"),
    re.compile(r"^find_"),
]

# Schema property names that suggest pagination support.
_PAGINATION_PARAMS = {"cursor", "page", "offset", "limit", "next_token", "page_token", "after", "before"}


def _looks_like_list_tool(name: str) -> bool:
    """Return True if the tool name suggests it returns a list of items."""
    return any(pattern.search(name) for pattern in _LIST_TOOL_PATTERNS)


def _has_pagination_params(schema: dict[str, Any]) -> bool:
    """Return True if the input schema has properties that suggest pagination."""
    properties = schema.get("properties", {})
    return bool(set(properties.keys()) & _PAGINATION_PARAMS)


@register_rule(
    name="list_tools_have_pagination",
    category="pagination",
    severity="info",
    description="List-returning tools should implement cursor-based pagination.",
)
def check_list_tools_have_pagination(
    tools: list[Any],
    **kwargs: Any,
) -> list[ValidationResult]:
    """Check that tools whose names suggest list operations have pagination parameters."""
    rule: ValidationRule = check_list_tools_have_pagination._rule  # type: ignore[attr-defined]
    results: list[ValidationResult] = []

    for tool in tools:
        if not _looks_like_list_tool(tool.name):
            # Not a list tool — skip.
            continue

        schema = tool.input_schema or {}

        if _has_pagination_params(schema):
            results.append(ValidationResult(
                rule=rule,
                passed=True,
                message=f"Tool '{tool.name}' has pagination parameters.",
                tool_name=tool.name,
            ))
        else:
            results.append(ValidationResult(
                rule=rule,
                passed=False,
                message=(
                    f"Tool '{tool.name}' appears to return a list but has no "
                    f"pagination parameters (cursor, offset, limit, etc.). "
                    f"Consider adding cursor-based pagination for large result sets."
                ),
                tool_name=tool.name,
            ))

    return results
