"""run.py — Lab 10 demo (offline): Semantic Kernel plugins, an MCP server/client,
and the BRIDGE (an MCP tool consumed as a kernel function — MCP decouples tools
from frameworks).

    python run.py
"""
from __future__ import annotations

from mcp_mini import MCPClient, build_core_banking_server
from sk_mini import BankingPlugin, Kernel


def line(t): print("\n" + "=" * 66 + f"\n{t}\n" + "=" * 66)


def main() -> None:
    line("1) Semantic-Kernel-style: a kernel hosts plugins of functions")
    kernel = Kernel()
    kernel.add_plugin(BankingPlugin({"AE070331234567890123456": 1250.0}), "banking")
    print("  function catalog an LLM planner sees:")
    for fv in kernel.functions():
        print(f"    - {fv.plugin}.{fv.name}: {fv.description}")
    print("  invoke banking.get_balance ->",
          kernel.invoke("banking", "get_balance", account_id="AE070331234567890123456"))

    line("2) MCP: discover and call tools/resources/prompts over the protocol")
    client = MCPClient(build_core_banking_server())
    print("  tools/list ->", [t["name"] for t in client.list_tools()])
    print("  tools/call get_balance ->",
          client.call_tool("get_balance",
                           {"account_id": "AE070331234567890123456", "user": "user_amal"}))
    print("  resources/read dispute policy ->",
          client.read_resource("bank://policies/dispute")[:60], "...")
    print("  prompts/get grounded_answer ->",
          client.get_prompt("grounded_answer", {"sources": "[doc:1]"})[:60], "...")

    line("3) MCP enforces permissions in the SERVER, not the prompt")
    try:
        client.call_tool("get_balance",
                        {"account_id": "AE070331234567890123456", "user": "mallory"})
    except RuntimeError as e:
        print("  unauthorized user blocked by the server:", e)

    line("4) BRIDGE: expose an MCP tool as a kernel function (write once, use anywhere)")
    kernel.register_function(
        "core_banking", "get_balance",
        "Balance via the core-banking MCP server.",
        lambda account_id, user: client.call_tool(
            "get_balance", {"account_id": account_id, "user": user}))
    print("  kernel now has",
          [f"{f.plugin}.{f.name}" for f in kernel.functions()])
    print("  invoke the MCP-backed function via the kernel ->",
          kernel.invoke("core_banking", "get_balance",
                       account_id="AE070331234567890123456", user="user_amal"))
    print("\n  -> the SAME core-banking tool is now usable by a Semantic-Kernel /")
    print("     Agent-Framework planner AND any other MCP host, with no rewrite.")


if __name__ == "__main__":
    main()
