"""
Agent服务名称映射器

负责在Agent的本地名称和全局名称之间进行转换：
- 本地名称：Agent看到的原始服务名（如 "demo"）
- 全局名称：内部存储的带后缀名称（如 "demobyagent1"）

设计原则：
1. Agent在自己空间中只看到原始名称
2. 内部存储和同步使用带后缀的全局名称
3. 提供双向转换和过滤功能
"""

import logging
from typing import Dict, Any, List, Optional, Tuple

logger = logging.getLogger(__name__)


class AgentServiceMapper:
    """Agent服务名称映射器"""
    
    def __init__(self, agent_id: str):
        """
        初始化映射器
        
        Args:
            agent_id: Agent ID
        """
        self.agent_id = agent_id
        self.suffix = f"by{agent_id}"
        
    def to_global_name(self, local_name: str) -> str:
        """
        本地名称转换为全局名称
        
        Args:
            local_name: Agent看到的原始服务名
            
        Returns:
            全局存储的带后缀服务名
        """
        return f"{local_name}{self.suffix}"
    
    def to_local_name(self, global_name: str) -> str:
        """
        全局名称转换为本地名称
        
        Args:
            global_name: 全局存储的带后缀服务名
            
        Returns:
            Agent看到的原始服务名
        """
        if global_name.endswith(self.suffix):
            return global_name[:-len(self.suffix)]
        return global_name
    
    def is_agent_service(self, global_name: str) -> bool:
        """
        判断服务是否属于当前Agent
        
        Args:
            global_name: 全局服务名
            
        Returns:
            是否属于当前Agent
        """
        return global_name.endswith(self.suffix)
    
    def filter_agent_services(self, global_services: Dict[str, Any]) -> Dict[str, Any]:
        """
        从全局服务中过滤出属于当前Agent的服务，并转换为本地名称
        
        Args:
            global_services: 全局服务配置字典
            
        Returns:
            本地服务配置字典（使用原始名称）
        """
        local_services = {}
        
        for global_name, config in global_services.items():
            if self.is_agent_service(global_name):
                local_name = self.to_local_name(global_name)
                local_services[local_name] = config
                logger.debug(f"Mapped service: {global_name} -> {local_name}")
        
        return local_services
    
    def convert_service_list_to_local(self, global_service_infos: List[Any]) -> List[Any]:
        """
        将全局服务信息列表转换为本地服务信息列表
        
        Args:
            global_service_infos: 全局服务信息列表
            
        Returns:
            本地服务信息列表（使用原始名称）
        """
        local_service_infos = []
        
        for service_info in global_service_infos:
            if self.is_agent_service(service_info.name):
                # 创建新的服务信息对象，使用本地名称
                local_name = self.to_local_name(service_info.name)
                
                # 复制服务信息，但使用本地名称
                # 注意：ServiceInfo没有tools属性，工具信息需要单独获取
                local_service_info = type(service_info)(
                    name=local_name,
                    transport_type=service_info.transport_type,
                    status=service_info.status,
                    tool_count=service_info.tool_count,
                    keep_alive=service_info.keep_alive,
                    url=getattr(service_info, 'url', ''),
                    working_dir=getattr(service_info, 'working_dir', None),
                    env=getattr(service_info, 'env', None),
                    last_heartbeat=getattr(service_info, 'last_heartbeat', None),
                    command=getattr(service_info, 'command', None),
                    args=getattr(service_info, 'args', None),
                    package_name=getattr(service_info, 'package_name', None),
                    state_metadata=getattr(service_info, 'state_metadata', None),
                    last_state_change=getattr(service_info, 'last_state_change', None),
                    client_id=getattr(service_info, 'client_id', None)
                )
                
                local_service_infos.append(local_service_info)
                logger.debug(f"Converted service info: {service_info.name} -> {local_name}")
        
        return local_service_infos
    

    
    def find_global_tool_name(self, local_tool_name: str, available_tools: List[str]) -> Optional[str]:
        """
        根据本地工具名称查找对应的全局工具名称
        
        Args:
            local_tool_name: 本地工具名称（如 "demo_get_weather"）
            available_tools: 可用的全局工具名称列表
            
        Returns:
            对应的全局工具名称，如果找不到则返回None
        """
        # 解析本地工具名称
        if "_" not in local_tool_name:
            # 如果没有下划线，可能是直接的工具名
            return None
        
        local_service_name, tool_suffix = local_tool_name.split("_", 1)
        global_service_name = self.to_global_name(local_service_name)
        expected_global_tool_name = f"{global_service_name}_{tool_suffix}"
        
        # 在可用工具中查找
        if expected_global_tool_name in available_tools:
            logger.debug(f"Found global tool: {local_tool_name} -> {expected_global_tool_name}")
            return expected_global_tool_name
        
        # 如果找不到精确匹配，尝试模糊匹配
        for global_tool_name in available_tools:
            if global_tool_name.startswith(f"{global_service_name}_"):
                tool_part = global_tool_name[len(f"{global_service_name}_"):]
                if tool_part == tool_suffix:
                    logger.debug(f"Found global tool (fuzzy): {local_tool_name} -> {global_tool_name}")
                    return global_tool_name
        
        logger.warning(f"Could not find global tool for local tool: {local_tool_name}")
        return None
    
    def convert_config_to_local(self, global_config: Dict[str, Any]) -> Dict[str, Any]:
        """
        将全局配置转换为本地配置（Agent视角）
        
        Args:
            global_config: 全局配置（包含所有服务）
            
        Returns:
            本地配置（只包含当前Agent的服务，使用原始名称）
        """
        if "mcpServers" not in global_config:
            return {"mcpServers": {}}
        
        local_servers = self.filter_agent_services(global_config["mcpServers"])
        
        return {
            "mcpServers": local_servers,
            # 保留其他配置项
            **{k: v for k, v in global_config.items() if k != "mcpServers"}
        }
    
    def convert_config_to_global(self, local_config: Dict[str, Any]) -> Dict[str, Any]:
        """
        将本地配置转换为全局配置（用于存储）
        
        Args:
            local_config: 本地配置（使用原始名称）
            
        Returns:
            全局配置（使用带后缀名称）
        """
        if "mcpServers" not in local_config:
            return local_config
        
        global_servers = {}
        for local_name, config in local_config["mcpServers"].items():
            global_name = self.to_global_name(local_name)
            global_servers[global_name] = config
            logger.debug(f"Converted config: {local_name} -> {global_name}")
        
        return {
            "mcpServers": global_servers,
            # 保留其他配置项
            **{k: v for k, v in local_config.items() if k != "mcpServers"}
        }
