"""Shared Agent Loop helpers for AI providers with tool_use support."""

from __future__ import annotations

import uuid
from typing import Any

from src.plugins.mcp.interfaces import MCPTool, MCPToolProvider, MCPToolResult
from src.services.ai_providers.permissions import filter_tools_for_agent
from src.services.ai_providers.tool_schema import tool_by_provider_name


class AgentToolExecutor:
    """Execute provider-safe tool names against MCP providers with audit context."""

    def __init__(
        self,
        *,
        available_tools: list[MCPTool],
        providers: dict[str, MCPToolProvider],
        agent_role: str,
        incident_id: str | None = None,
        session_id: str | None = None,
        flywheel_node: str | None = None,
    ) -> None:
        self.available_tools = filter_tools_for_agent(available_tools, agent_role)
        self.providers = providers
        self.agent_role = agent_role
        self.incident_id = incident_id
        self.session_id = session_id or str(uuid.uuid4())
        self.flywheel_node = flywheel_node

    async def execute(self, provider_tool_name: str, parameters: dict[str, Any]) -> MCPToolResult:
        """Resolve and execute one tool call."""

        tool = tool_by_provider_name(self.available_tools, provider_tool_name)
        if tool is None:
            return MCPToolResult(
                success=False,
                execution_id=str(uuid.uuid4()),
                error=f"Tool not allowed or unknown: {provider_tool_name}",
            )

        provider = self.providers.get(tool.server_name)
        if provider is None:
            return MCPToolResult(
                success=False,
                execution_id=str(uuid.uuid4()),
                error=f"Provider not available: {tool.server_name}",
            )

        audit_context = {
            "agent_role": self.agent_role,
            "session_id": self.session_id,
            "incident_id": self.incident_id,
            "flywheel_node": self.flywheel_node,
        }
        tool_parameters = dict(parameters)
        tool_parameters["_mcp_audit"] = {
            key: value for key, value in audit_context.items() if value
        }
        return await provider.execute(tool.name, tool_parameters)
