"""MENTORR Guide tools — MCP architecture education, capabilities reference, tutorials."""


# ---------------------------------------------------------------------------
# Content: MCP Architecture Explanations
# ---------------------------------------------------------------------------

MCP_ARCHITECTURE = {
    "overview": """
--- MCP Overview ---

The Model Context Protocol (MCP) is an open standard that defines how AI
applications (clients) connect to external tools and data sources (servers).
Think of it as a universal adapter -- instead of every AI app writing custom
integrations for every tool, MCP provides one protocol that works everywhere.

Architecture:

  Host Application (Claude Desktop, IDE, etc.)
      |
      v
  MCP Client  <---- JSON-RPC 2.0 ---->  MCP Server
                                            |
                                            v
                                    Local files, APIs,
                                    databases, hardware

Key concepts:
  - Host: The application the user interacts with (e.g., Claude Desktop)
  - Client: Lives inside the host, manages the connection to one server
  - Server: Exposes tools, resources, and prompts over the protocol

The protocol uses JSON-RPC 2.0 as its message format. Every interaction is
either a request (expects a response), a response, or a notification (fire
and forget, no response expected).

Three primitives servers can expose:
  1. Tools   -- Functions the AI can call (actions with side effects)
  2. Resources -- Data the AI can read (read-only, URI-addressed)
  3. Prompts -- Reusable prompt templates with arguments

The lifecycle:
  1. Client sends 'initialize' with its capabilities
  2. Server responds with its capabilities
  3. Client sends 'notifications/initialized'
  4. Normal operation (tool calls, resource reads, etc.)
  5. Either side can close the connection

Use 'explain_mcp_architecture' with topics like 'tools', 'resources',
'transports', 'lifecycle', 'prompts', 'sampling', or 'roots' for deep dives.
""",

    "transports": """
--- MCP Transports ---

A transport is the communication layer between client and server. MCP
supports three transport types:

1. STDIO (Standard I/O)
   - How it works: Client launches the server as a subprocess. Messages
     flow over stdin (client -> server) and stdout (server -> client).
   - When to use: Local tools, development, CLI integrations.
   - This is what MENTORR uses: mcp.run(transport='stdio')

2. SSE (Server-Sent Events)
   - How it works: Client connects via HTTP. Server pushes messages
     through an SSE stream. Being phased out in favor of Streamable HTTP.

3. Streamable HTTP
   - How it works: Client sends JSON-RPC requests as HTTP POST to a
     single endpoint. Supports both request-response and streaming.
   - When to use: Production deployments, remote servers, multi-client.

Transport selection in FastMCP:

    mcp.run(transport='stdio')               # Local subprocess
    mcp.run(transport='sse', port=8080)       # SSE server
    mcp.run(transport='streamable-http')      # Streamable HTTP
""",

    "tools": """
--- MCP Tools ---

Tools are the most important MCP primitive. They let a server expose
callable functions that the AI can invoke to perform actions.

In FastMCP, defining a tool is one decorator:

    @mcp.tool()
    def calculate_fret_layout(scale_length_inches: float,
                              number_of_frets: int = 22) -> str:
        \"\"\"Generates fret slotting table.\"\"\"
        return formatted_result

What happens behind the scenes:
  - Function name -> tool name
  - Docstring -> tool description
  - Type hints -> JSON Schema
  - Default values -> marked as optional in the schema
  - Return value -> wrapped in content blocks and sent back

Tools are MODEL-controlled (the AI decides when to call them).
Resources are USER-controlled (user selects which to attach).
""",

    "resources": """
--- MCP Resources ---

Resources expose data that the AI can read. They are URI-addressed,
read-only data sources.

Static Resource (fixed URI):
    @mcp.resource("mcp://docs/protocol",
                  name="protocol_spec",
                  mime_type="text/plain")
    def protocol_spec() -> str:
        return spec_content

Template Resource (dynamic URI with parameters):
    @mcp.resource("mcp://builds/{project_name}/status")
    def build_status(project_name: str) -> str:
        return f"Build {project_name}: 7 of 15 steps complete"
""",

    "prompts": """
--- MCP Prompts ---

Prompts are reusable prompt templates that a server can expose.

In FastMCP:
    @mcp.prompt()
    def debug_guitar_issue(symptom: str) -> str:
        return f"You are a master luthier. A customer reports: {symptom}"

Prompts are USER-controlled -- the user selects which prompt to use.
""",

    "lifecycle": """
--- MCP Lifecycle ---

Phase 1: Initialization (Handshake)
  Client -> Server:  initialize { protocolVersion, capabilities, clientInfo }
  Server -> Client:  response   { protocolVersion, capabilities, serverInfo }
  Client -> Server:  notifications/initialized

Phase 2: Normal Operation
  tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get

Phase 3: Shutdown
  Either side can close the connection.

With FastMCP and stdio transport, you don't manage any of this manually.
""",

    "sampling": """
--- MCP Sampling ---

Sampling is an advanced feature where the SERVER asks the CLIENT to
generate text using the AI model. This inverts the normal flow.

Normal flow:  User -> AI -> Tool call -> Server -> Result -> AI -> User
Sampling flow: Server (during tool execution) -> Client -> AI generates -> Server

This is a HUMAN-IN-THE-LOOP feature -- the client controls whether and how
sampling requests are fulfilled.
""",

    "roots": """
--- MCP Roots ---

Roots let the CLIENT tell the SERVER about relevant filesystem locations.
They define the boundaries of what the server should operate on.

Root format:
  { uri: "file:///Users/magus/MENTORR", name: "MENTORR Project" }

Roots are informational -- servers SHOULD respect them but the protocol
does not enforce access control.
""",
}

# ---------------------------------------------------------------------------
# Content: MENTORR System Capabilities
# ---------------------------------------------------------------------------

MENTORR_TOOLS = {
    "Luthier Physics": {
        "domain": "Build management, engineering calculations, knowledge retrieval",
        "tool_count": 15,
        "tools": {
            "register_project": "Add a project (luthier or music) to the Master Schedule with deadline and priority",
            "generate_work_day": "Create a prioritized daily schedule across all active projects given available hours",
            "forecast_materials": "Check upcoming build steps and list materials needed before you get blocked",
            "start_build": "Initialize a new guitar build project with a checklist from a template",
            "get_build_status": "View the current checklist and progress for a specific build",
            "update_build_step": "Mark a build step as Done, In Progress, or Pending with optional notes",
            "customize_build": "Add a custom step to an existing build checklist",
            "consult_library": "Semantic search across the luthier knowledge base using OpenAI embeddings",
            "save_project_specs": "Persist measurements and design specifications for a build",
            "get_project_specs": "Retrieve saved measurements and specs for a build",
            "get_wood_specs": "Look up physical properties (density, Janka, MOE) for a wood species",
            "calculate_fret_layout": "Generate a fret slotting table from scale length and fret count",
            "calculate_string_tension": "Compute per-string and total tension for a given gauge set and tuning",
            "calculate_saddle_placement": "Calculate saddle compensation offset for proper intonation",
            "calculate_neck_angle_geometry": "Calculate target bridge thickness from action and saddle protrusion",
        },
    },
    "Shelley Inventory": {
        "domain": "Tonewood inventory scraping, search, and analytics",
        "tool_count": 6,
        "tools": {
            "update_shelley_inventory": "Scrape Shelley Hardwoods catalog and sync to master inventory",
            "update_exotic_inventory": "Scrape Exotic Wood Zone catalog and sync to master inventory",
            "update_stewmac_inventory": "Scrape StewMac sitemap-based catalog and sync to master inventory",
            "process_lab_inbox": "Extract inventory data from receipt images using AI vision",
            "get_inventory_stats": "Summary statistics grouped by seller and wood species",
            "search_inventory": "Full-text search across the master inventory by query string",
        },
    },
    "Luthier Logic": {
        "domain": "Logical verification, diagnostics, design validation",
        "tool_count": 5,
        "tools": {
            "verify_truth_table": "Generate a rigorous truth table for a propositional logic formula",
            "diagnose": "Diagnose a guitar issue (buzz, intonation, dead spot) using logic trees",
            "recommend_wood": "Suggest tonewoods for a tonal goal and check inventory availability",
            "verify_design": "Validate a project design against common lutherie constraints",
            "explain_rule": "Explain the physics behind a lutherie rule of thumb",
        },
    },
    "MENTORR Guide": {
        "domain": "MCP protocol education, system documentation, tutorials",
        "tool_count": 3,
        "tools": {
            "explain_mcp_architecture": "Deep-dive explanation of MCP architecture topics",
            "get_mentorr_capabilities": "Structured reference of all tools in the MENTORR system",
            "start_tutorial": "Interactive walkthrough lessons on building MCP servers",
        },
    },
}

# ---------------------------------------------------------------------------
# Content: Tutorial Lessons
# ---------------------------------------------------------------------------

TUTORIALS = {
    1: {
        "title": "MCP Fundamentals",
        "content": """
--- Lesson 1 of 6: MCP Fundamentals ---

What you'll learn:
  - What MCP is and why it exists
  - The client-server architecture
  - How messages flow between components

The Problem MCP Solves:
  Without MCP, every AI application needs custom code to connect to every
  tool. MCP provides one protocol that works everywhere.

Minimal Server:

    from mcp.server.fastmcp import FastMCP
    mcp = FastMCP("My First Server")

    @mcp.tool()
    def hello(name: str) -> str:
        \"\"\"Say hello to someone.\"\"\"
        return f"Hello, {name}!"

    if __name__ == "__main__":
        mcp.run(transport='stdio')

Next: Lesson 2 - Writing Your First Tool
""",
    },
    2: {
        "title": "Writing Your First Tool",
        "content": """
--- Lesson 2 of 6: Writing Your First Tool ---

What you'll learn:
  - How @mcp.tool() works under the hood
  - Type hints and JSON Schema generation
  - Parameter defaults and validation

Type mapping:
  str   -> { "type": "string" }
  int   -> { "type": "integer" }
  float -> { "type": "number" }
  bool  -> { "type": "boolean" }

Always return str from tools for consistent output.

Next: Lesson 3 - Working with Resources
""",
    },
    3: {
        "title": "Working with Resources",
        "content": """
--- Lesson 3 of 6: Working with Resources ---

What you'll learn:
  - The difference between tools and resources
  - Static vs template resources
  - URI design and MIME types

Tools = ACTIONS (verbs). Resources = DATA (nouns).
Tools are model-controlled. Resources are user-controlled.

Next: Lesson 4 - Advanced Patterns
""",
    },
    4: {
        "title": "Advanced Patterns",
        "content": """
--- Lesson 4 of 6: Advanced Patterns ---

What you'll learn:
  - Error handling strategies
  - The Context object
  - Long-running operations and async tools

Return error info as strings, not exceptions, so the AI stays informed.

Next: Lesson 5 - Testing and Debugging
""",
    },
    5: {
        "title": "Testing and Debugging",
        "content": """
--- Lesson 5 of 6: Testing and Debugging ---

What you'll learn:
  - How to test MCP servers
  - Configuration for Claude Desktop / Claude Code
  - Common pitfalls

Common Pitfalls:
  1. Wrong Python path -> use venv Python
  2. print() in server code -> breaks stdio transport
  3. Missing docstrings -> AI can't use tools well

Next: Lesson 6 - Integration and Deployment
""",
    },
    6: {
        "title": "Integration and Deployment",
        "content": """
--- Lesson 6 of 6: Integration and Deployment ---

What you'll learn:
  - Multi-server architectures
  - How MENTORR is organized
  - Production deployment patterns

MENTORR is a unified server with 29 tools across 4 domains:
  Physics (15) + Inventory (6) + Logic (5) + Guide (3)

Install:
  pip install mentorr
  claude mcp add --transport stdio mentorr -- mentorr-server

You have completed all 6 lessons!
""",
    },
}

# ---------------------------------------------------------------------------
# Content: Protocol Specification Reference
# ---------------------------------------------------------------------------

PROTOCOL_SPEC_CONTENT = """\
=======================================
 MCP Protocol Quick Reference
=======================================

1. MESSAGE FORMAT (JSON-RPC 2.0)
   Request:      { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {...} }
   Response:     { "jsonrpc": "2.0", "id": 1, "result": {...} }
   Notification: { "jsonrpc": "2.0", "method": "notifications/initialized" }

2. INITIALIZATION HANDSHAKE
   Client -> Server:  initialize { protocolVersion, capabilities, clientInfo }
   Server -> Client:  response   { protocolVersion, capabilities, serverInfo }
   Client -> Server:  notifications/initialized

3. TOOL SCHEMA
   List:   tools/list -> [{ name, description, inputSchema }]
   Call:   tools/call  { name: "...", arguments: {...} }
   Result: { content: [{ type: "text", text: "..." }], isError: false }

4. TRANSPORT TYPES
   stdio:            stdin/stdout, newline-delimited JSON-RPC (local only)
   Streamable HTTP:  POST-based, optional SSE upgrade, session headers

5. FASTMCP PYTHON PATTERNS
   from mcp.server.fastmcp import FastMCP
   mcp = FastMCP("Server Name")

   @mcp.tool()
   def my_tool(param: str) -> str:
       \"\"\"Description becomes tool description.\"\"\"
       return "result"

   if __name__ == "__main__":
       mcp.run(transport='stdio')
"""


def register(mcp):
    """Register all MENTORR Guide tools and resources on the given FastMCP instance."""

    @mcp.tool()
    def explain_mcp_architecture(topic: str = "overview") -> str:
        """Deep-dive explanation of MCP (Model Context Protocol) architecture.

        topic: One of 'overview', 'transports', 'tools', 'resources', 'prompts',
               'lifecycle', 'sampling', 'roots'. Defaults to 'overview'.
        Returns formatted educational content about the specified MCP concept.
        """
        explanation = MCP_ARCHITECTURE.get(topic.lower().strip())
        if explanation:
            return explanation.strip()

        available = ", ".join(sorted(MCP_ARCHITECTURE.keys()))
        return (
            f"Unknown topic: '{topic}'\n\n"
            f"Available topics: {available}\n\n"
            "Example: explain_mcp_architecture(topic='tools')"
        )

    @mcp.tool()
    def get_mentorr_capabilities(format: str = "detailed") -> str:
        """Returns a structured reference of all tools in the MENTORR system.

        Lists every tool across all four domains: Luthier Physics (15 tools),
        Shelley Inventory (6 tools), Luthier Logic (5 tools), and MENTORR Guide (3 tools).

        format: 'detailed' for full descriptions, 'compact' for names only.
        """
        lines = ["--- MENTORR System Capabilities ---", ""]
        total = sum(s["tool_count"] for s in MENTORR_TOOLS.values())
        lines.append(f"Total: {total} tools across {len(MENTORR_TOOLS)} domains")
        lines.append("")

        for server_name, info in MENTORR_TOOLS.items():
            lines.append(f"=== {server_name} ({info['tool_count']} tools) ===")
            lines.append(f"Domain: {info['domain']}")
            lines.append("")

            for tool_name, description in info["tools"].items():
                if format.lower().strip() == "compact":
                    lines.append(f"  - {tool_name}")
                else:
                    lines.append(f"  {tool_name}")
                    lines.append(f"    {description}")
                    lines.append("")

            lines.append("")

        return "\n".join(lines).strip()

    @mcp.tool()
    def start_tutorial(lesson_number: int = 1) -> str:
        """Interactive walkthrough lessons on building MCP servers and tools.

        lesson_number: 1-6. Lessons cover fundamentals, tools, resources,
        advanced patterns, testing, and integration.

        Each lesson includes key concepts, code examples, and an exercise.
        """
        lesson = TUTORIALS.get(lesson_number)
        if lesson:
            return lesson["content"].strip()

        index_lines = ["--- MENTORR Tutorial Index ---", ""]
        index_lines.append(f"Available lessons (1-{len(TUTORIALS)}):")
        index_lines.append("")
        for num, info in sorted(TUTORIALS.items()):
            index_lines.append(f"  Lesson {num}: {info['title']}")
        index_lines.append("")
        index_lines.append("Usage: start_tutorial(lesson_number=1)")

        return "\n".join(index_lines)

    # Resource
    @mcp.resource(
        "mcp://docs/protocol",
        name="protocol_spec",
        description="Core MCP technical specification quick reference.",
        mime_type="text/plain",
    )
    def protocol_spec() -> str:
        """Return the MCP protocol specification reference document."""
        return PROTOCOL_SPEC_CONTENT
