"""
KgentikTools - Framework-agnostic tool resolver for Kgentik platform

This module provides seamless tool resolution from kgentik.yaml configuration,
supporting both local development and deployed environments.
"""
import os
import yaml
from pathlib import Path
from typing import List, Dict, Any, Optional
import importlib.util
import sys


class KgentikTools:
    """
    Framework-agnostic tool resolver for Kgentik platform.
    
    Automatically detects and loads tools from kgentik.yaml configuration.
    Works seamlessly in both local development and deployed environments.
    
    Example:
        >>> from kgentik.tools import KgentikTools
        >>> tools = KgentikTools()
        >>> tool_list = tools.get_tools()
    """
    
    def __init__(self, config_path: Optional[str] = None):
        """
        Initialize KgentikTools with optional config path.
        
        Args:
            config_path: Path to kgentik.yaml file. If None, auto-detects.
        """
        self.config_path = config_path or self._find_config()
        self._tools_cache: Dict[str, Any] = {}
        
        if not self.config_path:
            raise FileNotFoundError(
                "No kgentik.yaml found. Please ensure you're in a Kgentik project directory "
                "or provide a config_path."
            )
    
    def _find_config(self) -> Optional[str]:
        """Find kgentik.yaml in current or parent directories."""
        current = Path.cwd()
        for parent in [current] + list(current.parents):
            config = parent / "kgentik.yaml"
            if config.exists():
                return str(config)
        return None
    
    def _load_config(self) -> Dict[str, Any]:
        """Load and parse kgentik.yaml configuration."""
        try:
            with open(self.config_path, 'r') as f:
                return yaml.safe_load(f)
        except Exception as e:
            raise ValueError(f"Failed to parse kgentik.yaml: {e}")
    
    def get_tools(self) -> List[Any]:
        """
        Load all tools from kgentik.yaml
        
        Returns:
            List of tool functions/objects compatible with the framework
        """
        config = self._load_config()
        tools = []
        
        for tool_def in config.get("tools", []):
            tool = self._import_tool(tool_def["name"])
            if tool:
                tools.append(tool)
        
        return tools
    
    def _import_tool(self, name: str) -> Any:
        """
        Import tool from tools/ or .kgentik/tools/
        
        Args:
            name: Tool name (e.g., 'sqrt', 'email-sender')
            
        Returns:
            The tool object or None if not found
        """
        module_name = name.replace('-', '_')
        
        # Try tools/{name}.py first
        try:
            module = importlib.import_module(f'tools.{module_name}')
            return self._extract_tool(module)
        except ImportError:
            pass
        
        # Try .kgentik/tools/{name}.py
        try:
            config_dir = Path(self.config_path).parent
            kgentik_tools_path = config_dir / '.kgentik'
            if kgentik_tools_path.exists():
                sys.path.insert(0, str(kgentik_tools_path))
                try:
                    module = importlib.import_module(f'tools.{module_name}')
                    return self._extract_tool(module)
                finally:
                    sys.path.pop(0)
        except ImportError:
            pass
        
        print(f"Warning: Tool '{name}' not found")
        return None
    
    def _extract_tool(self, module) -> Any:
        """
        Extract @tool decorated function from module
        
        Args:
            module: The imported Python module
            
        Returns:
            The tool function/object
        """
        for attr_name in dir(module):
            if attr_name.startswith('_'):
                continue
            attr = getattr(module, attr_name)
            # Check if it's a LangChain tool (has 'name' attribute)
            if callable(attr) and hasattr(attr, 'name'):
                return attr
        return None
    
    def __iter__(self):
        """Make it iterable."""
        return iter(self.get_tools())
    
    def __len__(self):
        """Support len()."""
        return len(self.get_tools())
    
    def __repr__(self):
        """String representation."""
        return f"KgentikTools(config_path='{self.config_path}')"


# TODO: Future extensions
# - CLI tools (kgentik deploy, kgentik test, kgentik init)
# - Testing utilities for agents
# - Deployment helpers
# - Multi-framework adapters (LangGraph, LlamaIndex, CrewAI, etc.)
# - Tool validation and type checking
# - Hot-reloading for development
