#!/usr/bin/env python3
"""
lzwcai-mcp-agile-db MCP Server
数据库管理平台 MCP 工具服务，提供数据库管理、表/数据操作、技能、API 密钥、MQTT 同步、AI 训练等工具
"""

import json
import logging
import anyio

import mcp.types as types
from mcp.server import NotificationOptions, Server
from mcp.server.models import InitializationOptions
from mcp.server.stdio import stdio_server

from .utils.logger_config import setup_system_logging, get_logger
from .utils.api_client import AgileDBAPIClient
from .tools._base import get_registered_tools

# 初始化日志系统
setup_system_logging(app_name="lzwcai_mcp_agile_db", log_level=logging.DEBUG)
logger = get_logger(__name__)

# 初始化 MCP Server
server = Server("lzwcai_mcp_agile_db")

# 全局 API 客户端
_api_client: AgileDBAPIClient = None


def get_api_client() -> AgileDBAPIClient:
    """获取或创建 API 客户端"""
    global _api_client
    if _api_client is None:
        _api_client = AgileDBAPIClient()
    return _api_client


@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
    """列出所有可用工具"""
    logger.info("收到 ListTools 请求")
    
    tools = []
    for tool_cls in get_registered_tools():
        instance = tool_cls(get_api_client())
        tool_def = instance.to_tool_def()
        tools.append(
            types.Tool(
                name=tool_def["name"],
                description=tool_def["description"],
                inputSchema=tool_def["inputSchema"],
            )
        )
    
    logger.info(f"ListTools 响应: 返回 {len(tools)} 个工具")
    return tools


@server.call_tool()
async def handle_call_tool(
    name: str,
    arguments: dict | None,
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
    """调用工具"""
    logger.info(f"收到 CallTool 请求: name={name}")
    
    # 查找对应的工具类
    tool_cls = None
    for cls in get_registered_tools():
        if cls.name == name:
            tool_cls = cls
            break
    
    if tool_cls is None:
        logger.error(f"未找到工具: {name}")
        raise ValueError(f"未知工具: {name}")
    
    # 创建工具实例并执行
    client = get_api_client()
    tool_instance = tool_cls(client)
    
    try:
        result = await tool_instance.execute(arguments or {})
        
        logger.info(f"工具执行成功: {name}")
        logger.debug(f"工具返回结果: {json.dumps(result, ensure_ascii=False, indent=2)[:500]}...")
        
        return [
            types.TextContent(
                type="text",
                text=json.dumps(result, ensure_ascii=False, indent=2),
            )
        ]
    except Exception as e:
        logger.error(f"工具执行失败: {name}, 错误: {e}", exc_info=True)
        return [
            types.TextContent(
                type="text",
                text=json.dumps({"error": str(e), "tool_name": name}, ensure_ascii=False, indent=2),
            )
        ]


async def run_server():
    """运行 MCP Server (stdio 模式)"""
    try:
        async with stdio_server() as streams:
            await server.run(
                streams[0],
                streams[1],
                InitializationOptions(
                    server_name="lzwcai_mcp_agile_db",
                    server_version="0.1.12",
                    capabilities=server.get_capabilities(
                        notification_options=NotificationOptions(),
                        experimental_capabilities={},
                    ),
                ),
            )
    finally:
        # 释放全局 HTTP 客户端
        if _api_client is not None:
            await _api_client.close()


def main():
    """主入口"""
    logger.info("=" * 50)
    logger.info("lzwcai-mcp-agile-db MCP Server 启动")
    
    # 导入所有工具模块（触发装饰器注册）
    from . import tools  # noqa: F401
    
    logger.info(f"已注册工具数量: {len(get_registered_tools())}")
    logger.info("=" * 50)
    
    logger.info("开始运行 MCP Server (stdio 模式)")
    anyio.run(run_server)


if __name__ == "__main__":
    main()
