import abc
from typing import Dict, Any, Union, Optional
from abc import ABC, abstractmethod

class Tool_node(ABC):

    def __init__(self, name: str, description: str, tool_function: Optional[Any] = None):
       
        if not isinstance(name, str) or not name:
            raise ValueError("Tool_node name must be a non-empty string.")
        if not isinstance(description, str) or not description:
            raise ValueError("Tool_node description must be a non-empty string.")

        self.name = name
        self.description = description
        self._tool_function = tool_function 

    @abc.abstractmethod
    async def _execute_tool(self, **kwargs) -> Any:
       
        pass

    async def use_tool(self, task_description: str, **kwargs) -> str:
        
        print(f"[{self.name} Tool_node] Received task: '{task_description}' with params: {kwargs}")
        
        try:
            
            raw_result = await self._execute_tool(**kwargs)
            
 
            nl_description = self._format_result_to_natural_language(raw_result, task_description)
            return nl_description
            
        except Exception as e:
            error_message = f"[{self.name} Tool_node] Error executing tool for task '{task_description}': {e}"
            print(error_message)
            return error_message

    def _format_result_to_natural_language(self, raw_result: Any, task_description: str) -> str:
 
        if raw_result is None:
            return f"[{self.name} Tool_node] No result found for task: '{task_description}'."
  
        return f"[{self.name} Tool_node] The result for task '{task_description}' is: {str(raw_result)}"

    def get_description(self) -> str:
       
        return self.description

    def get_name(self) -> str:
    
        return self.name

