"""LangChain integration — wraps BaseTool instances with Surfinguard checks."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from ..client import Guard

# Action type inference from tool name keywords
_TOOL_TYPE_KEYWORDS: list[tuple[str, str]] = [
    ("url", "url"),
    ("browse", "url"),
    ("fetch", "url"),
    ("http", "url"),
    ("web", "url"),
    ("shell", "command"),
    ("bash", "command"),
    ("exec", "command"),
    ("terminal", "command"),
    ("read_file", "file_read"),
    ("file_read", "file_read"),
    ("read", "file_read"),
    ("write_file", "file_write"),
    ("file_write", "file_write"),
    ("write", "file_write"),
    ("file", "file_write"),
    ("search", "text"),
    ("query", "text"),
    ("run", "command"),
]


def _infer_action_type(tool_name: str) -> str:
    """Infer action type from tool name."""
    name_lower = tool_name.lower()
    for keyword, action_type in _TOOL_TYPE_KEYWORDS:
        if keyword in name_lower:
            return action_type
    return "command"  # Default


class SurfinguardToolGuard:
    """Wraps LangChain tools with Surfinguard security checks.

    Usage:
        from surfinguard import Guard
        from surfinguard.integrations.langchain import SurfinguardToolGuard

        guard = Guard(api_key="sg_live_...")
        tool_guard = SurfinguardToolGuard(guard)
        safe_tool = tool_guard.wrap(my_tool)
        # or wrap all tools at once
        safe_tools = tool_guard.wrap_all(tools)
    """

    def __init__(self, guard: Guard) -> None:
        self._guard = guard

    def wrap(self, tool: Any, action_type: str | None = None) -> Any:
        """Wrap a single LangChain BaseTool with security checks.

        Args:
            tool: A LangChain BaseTool instance.
            action_type: Override the inferred action type.

        Returns:
            A wrapped tool that checks inputs before execution.
        """
        resolved_type = action_type or _infer_action_type(getattr(tool, "name", ""))
        guard = self._guard

        original_run = tool._run

        def guarded_run(input_str: str, **kwargs: Any) -> Any:
            guard.check(resolved_type, input_str)
            return original_run(input_str, **kwargs)

        tool._run = guarded_run
        return tool

    def wrap_all(self, tools: list[Any], action_type: str | None = None) -> list[Any]:
        """Wrap multiple LangChain tools.

        Args:
            tools: List of BaseTool instances.
            action_type: Override action type for all tools (or None to infer per tool).

        Returns:
            List of wrapped tools.
        """
        return [self.wrap(tool, action_type) for tool in tools]
