"""Annotation validation rules."""

from __future__ import annotations

from typing import Any

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


@register_rule(
    name="tools_have_read_only_hint",
    category="annotations",
    severity="warning",
    description="Tools should have readOnlyHint annotation set.",
)
def check_tools_have_read_only_hint(
    tools: list[Any],
    **kwargs: Any,
) -> list[ValidationResult]:
    """Check that every tool has readOnlyHint in its annotations."""
    rule: ValidationRule = check_tools_have_read_only_hint._rule  # type: ignore[attr-defined]
    results: list[ValidationResult] = []

    for tool in tools:
        annotations = tool.annotations or {}
        if "readOnlyHint" in annotations:
            results.append(ValidationResult(
                rule=rule,
                passed=True,
                message=f"Tool '{tool.name}' has readOnlyHint annotation.",
                tool_name=tool.name,
            ))
        else:
            results.append(ValidationResult(
                rule=rule,
                passed=False,
                message=(
                    f"Tool '{tool.name}' is missing readOnlyHint annotation. "
                    f"Set readOnlyHint to true for read-only tools or false for tools with side effects."
                ),
                tool_name=tool.name,
            ))

    return results


@register_rule(
    name="destructive_tools_have_hint",
    category="annotations",
    severity="error",
    description="Tools with destructive side effects must have destructiveHint: true.",
)
def check_destructive_tools_have_hint(
    tools: list[Any],
    **kwargs: Any,
) -> list[ValidationResult]:
    """Check that tools marked as non-read-only have destructiveHint set.

    A tool is considered potentially destructive if readOnlyHint is explicitly
    set to false. In that case, destructiveHint should also be present so
    clients know whether the tool modifies data destructively.
    """
    rule: ValidationRule = check_destructive_tools_have_hint._rule  # type: ignore[attr-defined]
    results: list[ValidationResult] = []

    for tool in tools:
        annotations = tool.annotations or {}
        read_only = annotations.get("readOnlyHint")

        if read_only is True:
            # Explicitly read-only — destructiveHint not required.
            results.append(ValidationResult(
                rule=rule,
                passed=True,
                message=f"Tool '{tool.name}' is read-only; destructiveHint not required.",
                tool_name=tool.name,
            ))
        else:
            # readOnlyHint is False or absent — tool may have side effects.
            # destructiveHint should be present to declare intent.
            if "destructiveHint" not in annotations:
                results.append(ValidationResult(
                    rule=rule,
                    passed=False,
                    message=(
                        f"Tool '{tool.name}' is not marked read-only but has no destructiveHint. "
                        f"Set destructiveHint to true if the tool can delete/modify data, "
                        f"or false if side effects are non-destructive."
                    ),
                    tool_name=tool.name,
                ))
            else:
                results.append(ValidationResult(
                    rule=rule,
                    passed=True,
                    message=f"Tool '{tool.name}' has destructiveHint annotation set.",
                    tool_name=tool.name,
                ))

    return results
