"""Naming convention 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

# Match snake_case: lowercase letters/digits separated by underscores.
_SNAKE_CASE_RE = re.compile(r"^[a-z][a-z0-9]*(_[a-z0-9]+)*$")

# Match service_prefix pattern: at least one underscore separating prefix from action.
_PREFIXED_RE = re.compile(r"^[a-z][a-z0-9]*_[a-z][a-z0-9_]*$")


@register_rule(
    name="tool_names_snake_case",
    category="naming",
    severity="warning",
    description="Tool names should use snake_case with a service prefix (e.g. weather_get_current).",
)
def check_tool_names_snake_case(
    tools: list[Any],
    **kwargs: Any,
) -> list[ValidationResult]:
    """Check that every tool name is snake_case with a prefix."""
    rule: ValidationRule = check_tool_names_snake_case._rule  # type: ignore[attr-defined]
    results: list[ValidationResult] = []

    for tool in tools:
        name = tool.name
        if not _SNAKE_CASE_RE.match(name):
            results.append(ValidationResult(
                rule=rule,
                passed=False,
                message=f"Tool name '{name}' is not valid snake_case.",
                tool_name=name,
            ))
        elif not _PREFIXED_RE.match(name):
            results.append(ValidationResult(
                rule=rule,
                passed=False,
                message=(
                    f"Tool name '{name}' is snake_case but lacks a service prefix. "
                    f"Expected format: <prefix>_<action> (e.g. weather_get_current)."
                ),
                tool_name=name,
            ))
        else:
            results.append(ValidationResult(
                rule=rule,
                passed=True,
                message=f"Tool name '{name}' follows naming conventions.",
                tool_name=name,
            ))

    return results


@register_rule(
    name="server_name_convention",
    category="naming",
    severity="warning",
    description="Server name should follow {{service}}-mcp or {{service}}_mcp convention.",
)
def check_server_name_convention(
    tools: list[Any],
    *,
    server_name: str = "",
    **kwargs: Any,
) -> list[ValidationResult]:
    """Check that the server name ends with -mcp or _mcp."""
    rule: ValidationRule = check_server_name_convention._rule  # type: ignore[attr-defined]

    if not server_name:
        return [ValidationResult(
            rule=rule,
            passed=False,
            message="Server name is empty.",
            tool_name=None,
        )]

    if server_name.endswith("-mcp") or server_name.endswith("_mcp"):
        return [ValidationResult(
            rule=rule,
            passed=True,
            message=f"Server name '{server_name}' follows naming convention.",
            tool_name=None,
        )]

    return [ValidationResult(
        rule=rule,
        passed=False,
        message=(
            f"Server name '{server_name}' does not follow convention. "
            f"Expected '<service>-mcp' or '<service>_mcp'."
        ),
        tool_name=None,
    )]
