"""MCP tools emitter — inventory of current routes for the MCP server.

`mcp-server/lib/tools.js` is intentionally hand-curated: every tool has a
semantically rich description and handler. The shape model can't reconstruct
those from route metadata alone, so this emitter writes a *companion*
inventory rather than replacing tools.js.

The inventory is a JSON file listing every non-archived route with its HTTP
methods and dynamic params. When a new route ships, the inventory will include
it; reviewers can diff the inventory against tools.js to decide whether the
new route deserves an MCP wrapper.
"""
import json
from dataclasses import asdict

from livingcode.types import ShapeModel


def emit_mcp_tools(shape: ShapeModel) -> str:
    """Render the route surface as a JSON inventory for the MCP server."""
    active = [r for r in shape.routes if not r.archived]
    active.sort(key=lambda r: r.path)

    # Surface mutation-capable routes separately — those are the prime
    # candidates for MCP tool wrappers (agent-initiated side effects).
    mutation_methods = {"POST", "PATCH", "PUT", "DELETE"}
    mutations = [
        {
            "path": r.path,
            "methods": sorted(m for m in r.methods if m in mutation_methods),
            "dynamic_params": r.dynamic_params,
            "file_path": r.file_path,
        }
        for r in active
        if any(m in mutation_methods for m in r.methods)
    ]

    reads = [
        {
            "path": r.path,
            "methods": sorted(m for m in r.methods if m not in mutation_methods),
            "dynamic_params": r.dynamic_params,
            "file_path": r.file_path,
        }
        for r in active
        if any(m not in mutation_methods for m in r.methods)
    ]

    data = {
        "note": (
            "AUTO-GENERATED by livingcode. Inventory of the live API surface — "
            "reviewers should diff this against mcp-server/lib/tools.js to spot "
            "new routes that may deserve an MCP tool wrapper. tools.js is hand-"
            "curated on purpose and must not be regenerated from this file."
        ),
        "total_active_routes": len(active),
        "mutation_routes": mutations,
        "read_routes": reads,
        "all_routes": [asdict(r) for r in active],
    }
    return json.dumps(data, indent=2, default=str) + "\n"
