"""Gobby MCP server instructions.

Provides XML-structured instructions that teach agents how to use Gobby correctly.
These instructions are injected into the MCP server via FastMCP's `instructions` parameter.
"""

import logging

from gobby.prompts.sync import get_bundled_prompts_path

logger = logging.getLogger(__name__)

_FALLBACK_INSTRUCTIONS = """<gobby_system>

<tool_discovery>
Progressive discovery keeps token usage low — fetch schemas just-in-time, not upfront.

All servers follow the same discovery chain:
1. `list_mcp_servers()` — Discover available servers (required once per session)
2. `list_tools(server_name="...")` — See tool names per server (required once per server, per session)
3. `get_tool_schema(server_name, tool_name)` — Fetch parameter schema (required before first call)
4. `call_tool(server_name, tool_name, args)` — Execute the tool

The proxy validates parameters on every call_tool. If params are wrong, the error includes the full schema.
</tool_discovery>

<skills>
Discover skills with progressive discovery too:
1. `list_skills()` on `gobby-skills` — Names and descriptions
2. `get_skill(name="...")` — Full skill content (use after list_skills or search_skills)
3. `search_skills(query="...")` — Semantic search by topic (independent entry point, like list_skills)
</skills>

<caching>
Schema fetches are cached per session. Once you call `get_tool_schema(server_name, tool_name)`,
you can `call_tool` repeatedly WITHOUT re-fetching. Only fetch on first use.
</caching>

<common_mistakes>
WRONG — Loading all schemas upfront (wastes 30-40K tokens):
  for server in servers: get_tool_schema(server, tool) for each tool

RIGHT — Just-in-time discovery:
  get_tool_schema("gobby-tasks", "create_task")  # Learn required params
  call_tool("gobby-tasks", "create_task", {"title": "Fix bug", "session_id": "#123"})
</common_mistakes>

<variables>
`set_variable` and `get_variable` are top-level tools — no progressive discovery needed.
Call directly: set_variable(name="flag", value=true, session_id="#123")
</variables>

<rules>
- Create/claim a task before using Edit, Write, or NotebookEdit tools
- Pass session_id to create_task (required), claim_task (required), and close_task (optional, for tracking)
- NEVER load all tool schemas upfront — use progressive discovery
</rules>

</gobby_system>"""


def build_gobby_instructions() -> str:
    """Build instructions for Gobby MCP server.

    Loads instructions from the bundled prompt file on disk. Falls back to the
    hardcoded string if the file is missing (e.g., editable install without
    the prompts directory).

    Returns:
        XML-structured instructions string
    """
    prompt_file = get_bundled_prompts_path() / "mcp" / "progressive-discovery.md"
    if prompt_file.exists():
        try:
            raw = prompt_file.read_text(encoding="utf-8")
            # Strip frontmatter (between --- delimiters) to get just the content
            if raw.startswith("---"):
                parts = raw.split("---", 2)
                if len(parts) >= 3:
                    return parts[2].strip()
            return raw.strip()
        except OSError:
            logger.warning("Failed to read prompt file %s, using fallback", prompt_file)
    return _FALLBACK_INSTRUCTIONS
