import ast
from typing import Any
from common_logging import get_logger, log_execution

logger = get_logger(__name__)


class ToolExecutor:

    def __init__(self, timeout: int=5):
        self.timeout = timeout
        self.forbidden = {'os', 'sys', 'subprocess', 'eval', 'exec', '__import__'}

    def validate_code(self, code: str) -> bool:
        try:
            tree = ast.parse(code)
            for node in ast.walk(tree):
                if isinstance(node, ast.Import):
                    for alias in node.names:
                        if alias.name in self.forbidden:
                            raise ValueError(f'Forbidden: {alias.name}')
            return True
        except SyntaxError as e:
            raise ValueError(f'Syntax error: {e}') from None

    @log_execution(logger)
    def execute(self, code: str, params: dict[str, Any]) -> Any:
        self.validate_code(code)
        safe_globals = {'__builtins__': {'len': len, 'str': str, 'int': int, 'float': float, 'dict': dict, 'list': list, 'sum': sum, 'max': max, 'min': min}}
        local_vars = {'params': params}
        try:
            exec(code, safe_globals, local_vars)
        except Exception as e:
            logger.error(f"Tool execution failed: {e}")
            raise
        return local_vars.get('result')
