#!/usr/bin/env python3
"""Round 12: 聊天 E2E + 子服务连通性测试"""
import json, urllib.request, urllib.error, sys

BASE = "http://localhost:8080"
TOKEN_FILE = "/tmp/cyrene_test_token.txt"
SID_FILE = "/tmp/cyrene_test_sid.txt"

def req(method, path, body=None, token=None, timeout=10):
    url = f"{BASE}{path}"
    data = json.dumps(body).encode() if body else None
    r = urllib.request.Request(url, data=data, method=method)
    r.add_header("Content-Type", "application/json")
    if token:
        r.add_header("Authorization", f"Bearer {token}")
    try:
        resp = urllib.request.urlopen(r, timeout=timeout)
        return resp.status, resp.read().decode()
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()
    except Exception as e:
        return 0, str(e)

# ====== Step 1: Admin Login ======
print("=== Step 1: Admin Login ===")
status, body = req("POST", "/api/v1/auth/login",
    {"username":"yeij0942","password":"Jiang1143218570"})
print(f"  status={status}")
d = json.loads(body)
token = d.get("token", "")
print(f"  user_id={d.get('user_id')} has_token={'token' in d} token_len={len(token)}")

# ====== Step 2: 所有服务健康检查 ======
print("\n=== Step 2: 子服务健康检查 ===")
services = [
    ("ai-core (8081)", "http://localhost:8081/api/v1/health"),
    ("memory-service (8091)", "http://localhost:8091/api/v1/health"),
    ("tool-engine (8092)", "http://localhost:8092/api/v1/health"),
    ("voice-service (8093)", "http://localhost:8093/api/v1/health"),
    ("gateway (8080)", "http://localhost:8080/api/v1/health"),
]
for name, url in services:
    r = urllib.request.Request(url)
    try:
        resp = urllib.request.urlopen(r, timeout=5)
        body = resp.read().decode()
        print(f"  [{resp.status}] {name}: {body[:120]}")
    except Exception as e:
        print(f"  [FAIL] {name}: {e}")

# ====== Step 3: 获取/创建 Session ======
print("\n=== Step 3: Session 管理 ===")
status, body = req("GET", "/api/v1/sessions", token=token)
print(f"  GET /sessions status={status}")
try:
    sessions = json.loads(body)
    if isinstance(sessions, list) and len(sessions) > 0:
        sid = sessions[0].get("id", "")
        print(f"  existing session: {sid}")
    else:
        # 创建
        status, body = req("POST", "/api/v1/sessions", {"user_id": "admin"}, token=token)
        print(f"  POST /sessions status={status} body={body[:200]}")
        sid = json.loads(body).get("id", "")
        print(f"  new session: {sid}")
except Exception as e:
    print(f"  parse error: {e}")
    sid = ""

# ====== Step 4: 聊天消息发送 (测试 ai-core 转发) ======
print(f"\n=== Step 4: 聊天消息发送 (session={sid}) ===")
if sid and token:
    msg_body = {
        "session_id": sid,
        "message": "你好，请简单介绍一下你自己",
        "mode": "text"
    }
    status, body = req("POST", "/api/v1/chat", msg_body, token=token)
    print(f"  POST /api/v1/chat status={status}")
    if status == 404:
        print(f"  WARNING: /api/v1/chat 端点返回 404 - 端点可能未注册!")
        # 检查 gateway 日志
        import subprocess
        result = subprocess.run(["grep", "-i", "chat", "/tmp/gateway.log"], capture_output=True, text=True)
        print(f"  gateway log (chat): {result.stdout[:500]}")
    else:
        print(f"  response: {body[:500]}")
else:
    print("  SKIPPED: no session or token")

# ====== Step 5: 直接调用 ai-core chat ======
print("\n=== Step 5: 直接调用 ai-core /api/v1/chat ===")
ai_body = {
    "user_id": "admin",
    "session_id": sid or "test_session_001",
    "message": "Hello",
    "mode": "text"
}
r = urllib.request.Request("http://localhost:8081/api/v1/chat",
    data=json.dumps(ai_body).encode(),
    method="POST")
r.add_header("Content-Type", "application/json")
r.add_header("Accept", "text/event-stream")
try:
    resp = urllib.request.urlopen(r, timeout=30)
    print(f"  ai-core status={resp.status}")
    # 读取前5行 SSE
    lines = []
    for i in range(5):
        line = resp.readline().decode().strip()
        lines.append(line)
    print(f"  first 5 SSE lines: {lines}")
except Exception as e:
    print(f"  ai-core FAIL: {e}")

# ====== Step 6: memory-service 直调测试 ======
print("\n=== Step 6: memory-service 直调测试 ===")
r = urllib.request.Request("http://localhost:8091/api/v1/memory/search",
    data=json.dumps({"query": "test", "user_id": "admin", "limit": 5}).encode(),
    method="POST")
r.add_header("Content-Type", "application/json")
try:
    resp = urllib.request.urlopen(r, timeout=5)
    print(f"  memory/search status={resp.status} body={resp.read().decode()[:200]}")
except Exception as e:
    print(f"  memory/search FAIL: {e}")

# ====== Step 7: tool-engine 直调测试 ======
print("\n=== Step 7: tool-engine 直调测试 ===")
r = urllib.request.Request("http://localhost:8092/api/v1/tools",
    data=json.dumps({"action": "list"}).encode(),
    method="POST")
r.add_header("Content-Type", "application/json")
try:
    resp = urllib.request.urlopen(r, timeout=5)
    print(f"  tools/list status={resp.status} body={resp.read().decode()[:200]}")
except Exception as e:
    print(f"  tools/list FAIL: {e}")

# ====== Step 8: Gateway 路由检查 ======
print("\n=== Step 8: Gateway 路由检查 (哪些chat端点注册了) ===")
for path in ["/api/v1/chat", "/api/v1/chat/stream", "/api/v1/chat/send"]:
    status, _ = req("POST", path, {"message": "test"}, token=token)
    print(f"  POST {path}: {status}")

# ====== Step 9: WebSocket 端点检查 ======
print("\n=== Step 9: WebSocket 端点基本测试 ===")
import socket
# 先检查 /ws/chat 是否可访问 (HTTP层面)
r = urllib.request.Request("http://localhost:8080/ws/chat")
try:
    resp = urllib.request.urlopen(r, timeout=3)
    print(f"  GET /ws/chat (no upgrade): {resp.status}")
except urllib.error.HTTPError as e:
    print(f"  GET /ws/chat HTTP status: {e.code} body={e.read().decode()[:100]}")
except Exception as e:
    print(f"  GET /ws/chat: {e}")

# 保存 token 和 sid
with open(TOKEN_FILE, "w") as f:
    f.write(token)
with open(SID_FILE, "w") as f:
    f.write(sid or "")
print(f"\n[DONE] Token saved to {TOKEN_FILE}, sid={sid}")
