"""
Tool Registry and Base Tool Interface

This module defines the tool registry that manages all available tools
and provides a common interface for tool execution.
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, List, Optional
import importlib
import os


class BaseTool(ABC):
    """Base class for all agent tools"""
    
    def __init__(self, name: str, description: str):
        self.name = name
        self.description = description
    
    @abstractmethod
    def execute(self, query: str, context: Dict[str, Any]) -> Any:
        """
        Execute the tool with given query and context
        
        Args:
            query: User query or command
            context: Additional context including task analysis
            
        Returns:
            Tool execution result
        """
        pass
    
    @abstractmethod
    def get_capabilities(self) -> List[str]:
        """Return list of capabilities this tool provides"""
        pass
    
    def validate_input(self, query: str, context: Dict[str, Any]) -> bool:
        """Validate if the input is appropriate for this tool"""
        return True


class ToolRegistry:
    """Registry for managing all available tools"""
    
    def __init__(self):
        self.tools: Dict[str, BaseTool] = {}
        self._load_default_tools()
    
    def _load_default_tools(self):
        """Load all default tools"""
        try:
            # Import and register all tools
            from tools.python_tool import PythonTool
            from tools.web_browser_tool import WebBrowserTool
            from tools.file_system_tool import FileSystemTool
            from tools.screenshot_tool import ScreenshotTool
            from tools.web_scraper_tool import WebScraperTool
            from tools.diff_checker_tool import DiffCheckerTool
            from tools.content_generator_tool import ContentGeneratorTool
            from tools.react_project_tool import ReactProjectTool
            
            # Register tools
            self.register_tool(PythonTool())
            self.register_tool(WebBrowserTool())
            self.register_tool(FileSystemTool())
            self.register_tool(ScreenshotTool())
            self.register_tool(WebScraperTool())
            self.register_tool(DiffCheckerTool())
            self.register_tool(ContentGeneratorTool())
            self.register_tool(ReactProjectTool())
            
        except ImportError as e:
            print(f"Warning: Could not load some tools: {e}")
    
    def register_tool(self, tool: BaseTool):
        """Register a new tool"""
        self.tools[tool.name] = tool
        print(f"Registered tool: {tool.name}")
    
    def unregister_tool(self, tool_name: str):
        """Unregister a tool"""
        if tool_name in self.tools:
            del self.tools[tool_name]
            print(f"Unregistered tool: {tool_name}")
    
    def get_tool(self, tool_name: str) -> Optional[BaseTool]:
        """Get a tool by name"""
        return self.tools.get(tool_name)
    
    def get_available_tools(self) -> List[str]:
        """Get list of available tool names"""
        return list(self.tools.keys())
    
    def get_tool_descriptions(self) -> Dict[str, str]:
        """Get descriptions of all tools"""
        return {name: tool.description for name, tool in self.tools.items()}
    
    def get_tools_by_capability(self, capability: str) -> List[BaseTool]:
        """Get tools that provide a specific capability"""
        matching_tools = []
        for tool in self.tools.values():
            if capability in tool.get_capabilities():
                matching_tools.append(tool)
        return matching_tools
    
    def execute_tool(self, tool_name: str, query: str, context: Dict[str, Any]) -> Any:
        """Execute a tool by name"""
        tool = self.get_tool(tool_name)
        if not tool:
            return f"Tool '{tool_name}' not found"
        
        if not tool.validate_input(query, context):
            return f"Invalid input for tool '{tool_name}'"
        
        try:
            return tool.execute(query, context)
        except Exception as e:
            return f"Error executing tool '{tool_name}': {str(e)}"
    
    def get_tool_info(self) -> Dict[str, Dict[str, Any]]:
        """Get comprehensive information about all tools"""
        info = {}
        for name, tool in self.tools.items():
            info[name] = {
                "name": tool.name,
                "description": tool.description,
                "capabilities": tool.get_capabilities()
            }
        return info

