"""MCP server for codebase indexing."""

import argparse
import asyncio

import uvicorn
from loguru import logger
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool

from acetool.config import get_config, init_config
from acetool.logging_config import setup_logging
from acetool.tools import search_context_tool
from acetool.web import create_app

app = Server("acetool")


@app.list_tools()
async def list_tools() -> list[Tool]:
    """List available MCP tools.

    Returns:
        List of available tools
    """
    return [
        Tool(
            name="search_context",
            description="Search for relevant code context based on a query within a specific project. This tool automatically performs incremental indexing before searching, ensuring results are always up-to-date. Returns formatted text snippets from the codebase that are semantically related to your query. IMPORTANT: Use forward slashes (/) as path separators in project_root_path, even on Windows.",
            inputSchema={
                "type": "object",
                "properties": {
                    "project_root_path": {
                        "type": "string",
                        "description": "Absolute path to the project root directory. Use forward slashes (/) as separators. Example: C:/Users/username/projects/myproject",
                    },
                    "query": {
                        "type": "string",
                        "description": "Provide clear and complete Chinese natural language queries that are highly relevant to the questions raised by users, describing the content you are looking for (e.g., “应用启动时在哪里初始化日志配置的位置和配置方式？”, “用户登录流程中如何生成和校验access token？”), rather than a list of keywords. This helps the tool better understand the context and return more accurate code snippets with file paths and line numbers.",
                    },
                },
                "required": ["project_root_path", "query"],
            },
        ),
    ]


@app.call_tool()
async def call_tool(name: str, arguments: dict) -> dict:
    """Handle tool calls.

    Args:
        name: Tool name
        arguments: Tool arguments

    Returns:
        Tool execution results
    """
    logger.info(f"Tool called: {name} with arguments: {arguments}")

    if name == "search_context":
        return await search_context_tool(arguments)

    return {"type": "text", "text": f"Unknown tool: {name}"}


async def run_web_server(port: int) -> None:
    """Run the web management server.

    Args:
        port: Port to run the web server on
    """
    web_app = create_app()
    # Configure uvicorn to use loguru through InterceptHandler
    # This prevents uvicorn from polluting stdout (which breaks MCP stdio protocol)
    config_uvicorn = uvicorn.Config(
        web_app,
        host="0.0.0.0",
        port=port,
        log_level="warning",
        access_log=False,  # Disable access log to reduce noise
        log_config=None,   # Disable default logging config to use our interceptor
    )
    server = uvicorn.Server(config_uvicorn)
    await server.serve()


async def main(base_url: str | None = None, token: str | None = None, web_port: int | None = None) -> None:
    """Run the MCP server.

    Args:
        base_url: Override BASE_URL from command line
        token: Override TOKEN from command line
        web_port: Port for web management interface (None to disable)
    """
    try:
        config = init_config(base_url=base_url, token=token)
        config.validate()
        logger.info("Starting acetool MCP server...")
        logger.info(f"Configuration: index_storage_path={config.index_storage_path}, batch_size={config.batch_size}")
        logger.info(f"API: base_url={config.base_url}")

        if web_port:
            logger.info(f"Starting web management interface on port {web_port}")
            web_task = asyncio.create_task(run_web_server(web_port))

        async with stdio_server() as (read_stream, write_stream):
            await app.run(read_stream, write_stream, app.create_initialization_options())

        if web_port:
            web_task.cancel()

    except Exception:
        logger.exception("Server error")
        raise


def run() -> None:
    """Entry point for the MCP server."""
    parser = argparse.ArgumentParser(description="Acetool MCP Server for codebase indexing")
    parser.add_argument("--base-url", type=str, help="Override BASE_URL configuration")
    parser.add_argument("--token", type=str, help="Override TOKEN configuration")
    parser.add_argument("--web-port", type=int, help="Enable web management interface on specified port (e.g., 8080)")

    args = parser.parse_args()

    # If web interface is enabled, initialize log broadcaster before setting up logging
    # This ensures the WebSocket handler is preserved
    if args.web_port:
        from acetool.web.log_handler import get_log_broadcaster
        get_log_broadcaster()  # Initialize the broadcaster

    # Setup logging after log broadcaster is initialized
    # Intercept stdlib logging (uvicorn, fastapi) to prevent stdout pollution
    setup_logging(intercept_stdlib=True)

    asyncio.run(main(base_url=args.base_url, token=args.token, web_port=args.web_port))


if __name__ == "__main__":
    run()

