import asyncio
import json
import os
from typing import Any

from agent_framework import MCPStreamableHTTPTool


def as_json(value: Any) -> Any:
    if hasattr(value, "model_dump"):
        return value.model_dump(mode="json", by_alias=True)
    if isinstance(value, list):
        return [as_json(item) for item in value]
    if isinstance(value, dict):
        return {str(key): as_json(item) for key, item in value.items()}
    return value


async def main() -> None:
    endpoint = os.environ.get("MCP_ENDPOINT")
    if not endpoint:
        raise SystemExit("Set MCP_ENDPOINT to your reviewed https://.../mcp endpoint.")

    async with MCPStreamableHTTPTool(
        name="open-for-agents",
        url=endpoint,
        load_tools=True,
        load_prompts=False,
        request_timeout=20,
        terminate_on_close=False,
    ) as mcp_tool:
        if mcp_tool.session is None:
            raise RuntimeError("The MCP session did not initialize.")

        listed = as_json(await mcp_tool.session.list_tools())
        tools = listed["tools"]
        for tool in tools:
            annotations = tool["annotations"]
            if (
                annotations["readOnlyHint"] is not True
                or annotations["openWorldHint"] is not False
            ):
                raise RuntimeError(f"Unexpected annotations for {tool['name']}.")

        calls: dict[str, Any] = {}
        for name, arguments in (
            ("get_site_info", {}),
            ("list_posts", {"per_page": 3}),
            ("woo_search_products", {"per_page": 3}),
        ):
            result = as_json(await mcp_tool.session.call_tool(name, arguments))
            if result["isError"] is True:
                raise RuntimeError(f"{name} returned an error.")
            calls[name] = result["structuredContent"]

        large = as_json(
            await mcp_tool.session.call_tool(
                "woo_search_products",
                {"per_page": 6},
            )
        )
        projected = json.loads(large["content"][0]["text"].split("\n\n", 1)[1])
        bounded = projected["_open_for_agents"]
        if (
            large["isError"] is True
            or bounded["truncated"] is not True
            or bounded["reason"] != "output_budget"
            or bounded["max_chars"] != 1500
        ):
            raise RuntimeError("The bounded output contract did not match.")

        print(
            json.dumps(
                {
                    "endpoint": endpoint,
                    "tools": [
                        {
                            "name": tool["name"],
                            "annotations": tool["annotations"],
                        }
                        for tool in tools
                    ],
                    "representative_calls": calls,
                    "bounded_output": bounded,
                },
                indent=2,
            )
        )


if __name__ == "__main__":
    asyncio.run(main())
