#!/usr/bin/env python3
import base64
import json
import sys
import urllib.error
import urllib.parse
import urllib.request


if len(sys.argv) != 2:
    raise SystemExit("usage: agent_protocol_http_contract.py BASE_URL")
base = sys.argv[1].rstrip("/")


def request(path, method="GET", payload=None, headers=None, form=None, expected=200):
    body = None
    request_headers = dict(headers or {})
    if payload is not None:
        body = json.dumps(payload).encode()
        request_headers["Content-Type"] = "application/json"
    elif form is not None:
        body = urllib.parse.urlencode(form).encode()
        request_headers["Content-Type"] = "application/x-www-form-urlencoded"
    req = urllib.request.Request(base + path, data=body, headers=request_headers, method=method)
    try:
        with urllib.request.urlopen(req, timeout=10) as response:
            status = response.status
            raw = response.read()
    except urllib.error.HTTPError as error:
        status = error.code
        raw = error.read()
    assert status == expected, (path, status, raw[:300])
    if not raw:
        return None
    return json.loads(raw)


metadata = request("/.well-known/oauth-authorization-server")
assert metadata["issuer"] == "https://api.yokesen.com"
assert metadata["token_endpoint"] == "https://api.yokesen.com/oauth/token"
assert metadata["code_challenge_methods_supported"] == ["S256"]
assert set(metadata["scopes_supported"]) == {"public:read", "diagnosis:start", "profile:read"}

resource = request("/.well-known/oauth-protected-resource")
assert resource["resource"] == "https://api.yokesen.com"
assert resource["authorization_servers"] == ["https://api.yokesen.com"]

registration = request(
    "/oauth/register",
    method="POST",
    payload={"client_name": "YOKESEN disposable contract", "scope": "public:read diagnosis:start"},
    expected=201,
)
client_id = registration["client_id"]
client_secret = registration["client_secret"]
assert client_id.startswith("yk_agent_")
assert len(client_secret) >= 32

basic = base64.b64encode((client_id + ":" + client_secret).encode()).decode()
token = request(
    "/oauth/token",
    method="POST",
    headers={"Authorization": "Basic " + basic},
    form={"grant_type": "client_credentials", "scope": "public:read"},
)
access_token = token["access_token"]
assert token["token_type"] == "Bearer"
assert token["scope"] == "public:read"

claims = request("/oauth/claims", headers={"Authorization": "Bearer " + access_token})
assert claims["active"] is True
assert claims["client_id"] == client_id
assert claims["scope"] == "public:read"

request(
    "/oauth/revoke",
    method="POST",
    headers={"Authorization": "Basic " + basic},
    form={"token": access_token},
)
revoked = request(
    "/oauth/claims",
    headers={"Authorization": "Bearer " + access_token},
    expected=401,
)
assert revoked["error"] == "invalid_token"

mcp = request(
    "/mcp",
    method="POST",
    payload={
        "jsonrpc": "2.0", "id": 1, "method": "initialize",
        "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "test", "version": "1"}},
    },
)
assert mcp["result"]["protocolVersion"] == "2025-06-18"
assert mcp["result"]["serverInfo"]["name"] == "YOKESEN Public Business Context"

tools = request("/mcp", method="POST", payload={"jsonrpc": "2.0", "id": 2, "method": "tools/list"})
tool_names = {tool["name"] for tool in tools["result"]["tools"]}
assert tool_names == {"yokesen_public_context", "yokesen_business_diagnosis_start"}

a2a = request(
    "/a2a",
    method="POST",
    payload={
        "jsonrpc": "2.0", "id": 3, "method": "message/send",
        "params": {"message": {"messageId": "contract", "role": "ROLE_USER", "parts": [{"text": "What is YOKESEN?"}]}},
    },
)
answer = a2a["result"]["message"]["parts"][0]["text"]
assert a2a["result"]["message"]["role"] == "ROLE_AGENT"
assert "YOKESEN" in answer
for forbidden in ["/home/", "/opt/", "Deric", "Gia", "OAuth secret"]:
    assert forbidden not in answer

print("agent_protocol_http_contract: PASS")
