#!/usr/bin/env python3
"""
AURORA MCP Server - FastMCP implementation.

Provides Model Context Protocol server for AURORA codebase indexing and search.
"""

import argparse
import sys
from pathlib import Path
from typing import Optional


try:
    from fastmcp import FastMCP
except ImportError:
    print("Error: FastMCP not installed. Install with: pip install fastmcp", file=sys.stderr)
    sys.exit(1)

from aurora_mcp.tools import AuroraMCPTools


class AuroraMCPServer:
    """MCP Server for AURORA codebase tools."""

    def __init__(
        self, db_path: str | None = None, config_path: str | None = None, test_mode: bool = False
    ):
        """
        Initialize AURORA MCP Server.

        Args:
            db_path: Path to SQLite database (default: ~/.aurora/memory.db)
            config_path: Path to AURORA config file (default: ~/.aurora/config.json)
            test_mode: If True, skip FastMCP initialization (for testing)
        """
        self.db_path = db_path or str(Path.home() / ".aurora" / "memory.db")
        self.config_path = config_path or str(Path.home() / ".aurora" / "config.json")
        self.test_mode = test_mode

        # Initialize tools
        self.tools = AuroraMCPTools(self.db_path, self.config_path)

        # Initialize FastMCP server only if not in test mode
        if not test_mode:
            self.mcp = FastMCP("aurora")
            # Register tools
            self._register_tools()
        else:
            self.mcp = None

    def _register_tools(self) -> None:
        """Register MCP tools with the server."""

        @self.mcp.tool()
        def aurora_search(query: str, limit: int = 10) -> str:
            """
            Search AURORA indexed codebase.

            Args:
                query: Search query string
                limit: Maximum number of results (default: 10)

            Returns:
                JSON string with search results
            """
            return self.tools.aurora_search(query, limit)

        @self.mcp.tool()
        def aurora_query(
            query: str,
            limit: int = 10,
            type_filter: str | None = None,
            verbose: bool = False,
        ) -> str:
            """
            Retrieve relevant context from AURORA memory without LLM inference.

            This tool provides intelligent context retrieval with complexity assessment
            and confidence scoring. It returns structured context for the host LLM
            (Claude Code CLI) to reason about, rather than calling external LLM APIs.

            Args:
                query: Natural language query string (required)
                limit: Maximum number of chunks to retrieve (default: 10)
                type_filter: Filter by memory type - "code", "reas", "know", or None (default: None)
                verbose: Include detailed metadata in response (default: False)

            Returns:
                JSON string with:
                - context: Retrieved memory chunks with content, metadata, and relevance scores
                - assessment: Complexity assessment and retrieval confidence score
                - metadata: Database stats and result counts

            Examples:
                Basic retrieval:
                    aurora_query("What is a Python decorator?")

                Type-filtered retrieval:
                    aurora_query("async patterns", type_filter="code", limit=5)

                Detailed metadata:
                    aurora_query("SOAR pipeline", verbose=True)

            Note:
                No API key required. This tool runs inside Claude Code CLI which
                provides the LLM reasoning capabilities. For standalone usage with
                LLM responses, use the CLI command: $ aur query "your question"
            """
            return self.tools.aurora_query(query, limit, type_filter, verbose)

        @self.mcp.tool()
        def aurora_get(index: int) -> str:
            """
            Retrieve a full chunk by index from the last search results.

            This tool allows you to get the complete content of a specific result
            from your last aurora_search or aurora_query call. Results are numbered
            starting from 1 (1-indexed).

            Workflow:
            1. Call aurora_search or aurora_query to get numbered results
            2. Review the list and choose which result you want
            3. Call aurora_get(N) to retrieve the full chunk for result N

            Args:
                index: 1-indexed position in last search results (must be >= 1)

            Returns:
                JSON string with:
                - chunk: Complete chunk with all metadata (id, type, content, file_path, etc.)
                - metadata: Index position and total count

            Examples:
                After aurora_search("async patterns"):
                    aurora_get(1)  # Get first result
                    aurora_get(3)  # Get third result

            Note:
                Session cache expires after 10 minutes. Results are stored per-session
                and cleared when a new search is performed.
            """
            return self.tools.aurora_get(index)

    def run(self) -> None:
        """Run the MCP server."""
        self.mcp.run()

    def list_tools(self) -> None:
        """List all available tools (for testing)."""
        print("AURORA MCP Server - Available Tools:")
        print("=" * 50)

        # Get registered tools from FastMCP
        tools = [
            ("aurora_search", "Search indexed codebase with semantic + keyword search"),
            ("aurora_query", "Retrieve relevant context with SOAR pipeline orchestration"),
            ("aurora_get", "Get full chunk by index from last search results"),
        ]

        for name, description in tools:
            print(f"\n{name}:")
            print(f"  {description}")

        print("\n" + "=" * 50)
        print(f"Total tools: {len(tools)}")
        print(f"Database: {self.db_path}")
        print(f"Config: {self.config_path}")


def main() -> None:
    """Main entry point for MCP server CLI."""
    parser = argparse.ArgumentParser(
        description="AURORA MCP Server - Model Context Protocol integration",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    parser.add_argument(
        "--db-path",
        type=str,
        help="Path to SQLite database (default: ~/.aurora/memory.db)",
    )

    parser.add_argument(
        "--config",
        type=str,
        help="Path to AURORA config file (default: ~/.aurora/config.json)",
    )

    parser.add_argument(
        "--test",
        action="store_true",
        help="Test mode: start server and list available tools",
    )

    args = parser.parse_args()

    # Create server instance
    server = AuroraMCPServer(db_path=args.db_path, config_path=args.config, test_mode=args.test)

    if args.test:
        print("AURORA MCP Server - Test Mode")
        print("=" * 50)
        server.list_tools()
        print("\nTest mode complete. Server initialized successfully!")
        sys.exit(0)

    # Run server
    print("Starting AURORA MCP Server...")
    print(f"Database: {server.db_path}")
    print(f"Config: {server.config_path}")
    server.run()


if __name__ == "__main__":
    main()
