"""Regex-based search transform."""

import re
from collections.abc import Sequence
from typing import Annotated, Any

from fastmcp.server.context import Context
from fastmcp.server.transforms.search.base import (
    BaseSearchTransform,
    _extract_searchable_text,
)
from fastmcp.tools.base import Tool


class RegexSearchTransform(BaseSearchTransform):
    """Search transform using regex pattern matching.

    Tools are matched against their name, description, and parameter
    information using ``re.search`` with ``re.IGNORECASE``.
    """

    def _make_search_tool(self) -> Tool:
        transform = self

        async def search_tools(
            pattern: Annotated[
                str,
                "Regex pattern to match against tool names, descriptions, and parameters",
            ],
            ctx: Context = None,  # type: ignore[assignment]  # ty:ignore[invalid-parameter-default]
        ) -> str | list[dict[str, Any]]:
            """Search for tools matching a regex pattern.

            Returns matching tool definitions in the same format as list_tools.
            """
            hidden = await transform._get_visible_tools(ctx)
            results = await transform._search(hidden, pattern)
            return await transform._render_results(results)

        return Tool.from_function(fn=search_tools, name=self._search_tool_name)

    async def _search(self, tools: Sequence[Tool], query: str) -> Sequence[Tool]:
        try:
            compiled = re.compile(query, re.IGNORECASE)
        except re.error:
            return []

        matches: list[Tool] = []
        for tool in tools:
            text = _extract_searchable_text(tool)
            if compiled.search(text):
                matches.append(tool)
                if len(matches) >= self._max_results:
                    break
        return matches
