"""
Phase 79: RAG Pipeline MCP Microservice Tools.

Exposes the Phase 62 RAG pipeline as MCP tools.
"""

from mcp.types import TextContent, Tool, ToolAnnotations

_SAFE_READ = ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)
_SAFE_WRITE = ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False)

TOOLS = [
    Tool(
        name="rag_index",
        description="Index a project directory for RAG retrieval. Chunks files and builds TF-IDF index.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_root": {"type": "string", "description": "Absolute path to project root"},
                "force": {"type": "boolean", "description": "Re-index all files even if unchanged"},
            },
            "required": ["project_root"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="rag_retrieve",
        description="Retrieve relevant code/doc chunks for a query using TF-IDF.",
        inputSchema={
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Search query"},
                "limit": {"type": "integer", "description": "Max results (default: 5)"},
                "source_filter": {"type": "string", "description": "Glob pattern for source files"},
            },
            "required": ["query"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_context",
        description="Get formatted RAG context ready for prompt injection.",
        inputSchema={
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "limit": {"type": "integer", "description": "Max chunks (default: 3)"},
                "max_chars": {"type": "integer", "description": "Max output chars (default: 2000)"},
            },
            "required": ["query"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_query_all",
        description="Search both codebase chunks AND knowledge base entries. Returns merged, ranked results from both sources.",
        inputSchema={
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Natural language query"},
                "limit": {"type": "integer", "description": "Max results (default: 5)"},
            },
            "required": ["query"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_stats",
        description="Get RAG index statistics.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_clear",
        description="Clear the entire RAG index.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_WRITE,
    ),
]


# ── Handlers ───────────────────────────────────────────────────────────────

import json


async def _handle_index(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import index_project
    try:
        stats = index_project(
            project_root=args["project_root"],
            force=args.get("force", False),
        )
        return [TextContent(type="text", text=json.dumps(stats, indent=2, default=str))]
    except ValueError as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_retrieve(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import retrieve
    results = retrieve(
        query=args["query"],
        limit=args.get("limit", 5),
        source_filter=args.get("source_filter"),
    )
    return [TextContent(type="text", text=json.dumps(results, indent=2, default=str))]


async def _handle_context(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import retrieve_for_prompt
    context = retrieve_for_prompt(
        query=args["query"],
        limit=args.get("limit", 3),
        max_chars=args.get("max_chars", 2000),
    )
    if not context:
        return [TextContent(type="text", text="No relevant context found.")]
    return [TextContent(type="text", text=context)]


async def _handle_stats(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import get_index_stats
    stats = get_index_stats()
    return [TextContent(type="text", text=json.dumps(stats, indent=2, default=str))]


async def _handle_query_all(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import retrieve_with_knowledge
    results = retrieve_with_knowledge(
        query=args["query"],
        limit=args.get("limit", 5),
    )
    return [TextContent(type="text", text=json.dumps(results, indent=2, default=str))]


async def _handle_clear(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import clear_index
    result = clear_index()
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


HANDLERS = {
    "rag_index": _handle_index,
    "rag_retrieve": _handle_retrieve,
    "rag_context": _handle_context,
    "rag_query_all": _handle_query_all,
    "rag_stats": _handle_stats,
    "rag_clear": _handle_clear,
}
