#!/usr/bin/env python3
"""
门桥接 · Gate Bridge · ICE-GL-ZY-AGT-GATE-005

铸渊要连接服务器？桥接提供所有Gatekeeper的凭据和通道。
不需要铸渊记住12台服务器的IP和密钥——桥接知道。

用法:
  python3 bridge.py list                    # 列出所有服务器
  python3 bridge.py connect BS-SG-001       # 获取连接信息
  python3 bridge.py exec BS-SG-001 "ls"     # 通过Gatekeeper执行命令
  python3 bridge.py scan                    # 扫描所有服务器在线状态
"""

import json
import os
import sys
import urllib.request
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent.parent

def load_gatekeepers():
    """加载所有Gatekeeper"""
    gk_path = REPO_ROOT / "brain" / "gatekeeper-deployment.json"
    if gk_path.exists():
        with open(gk_path) as f:
            data = json.load(f)
        return data
    return {"servers": []}

def list_servers():
    """列出所有服务器（不暴露密钥）"""
    data = load_gatekeepers()
    servers = []
    for s in data.get("servers", []):
        servers.append({
            "code": s["code"],
            "name": s.get("name", ""),
            "ip": s["ip"],
            "port": s["port"],
            "domain": s.get("domain", ""),
            "spec": s.get("spec", {}),
        })
    return {
        "total": len(servers),
        "domains": list(set(s.get("domain", "") for s in data.get("servers", []))),
        "servers": servers
    }

def get_connection(server_code):
    """获取指定服务器的完整连接信息（含密钥）"""
    data = load_gatekeepers()
    for s in data.get("servers", []):
        if s["code"] == server_code:
            return {
                "code": s["code"],
                "name": s.get("name"),
                "gatekeeper_url": f"http://{s['ip']}:{s['port']}/exec",
                "auth_header": f"Bearer {s['key']}",
                "curl_example": f'curl -X POST http://{s["ip"]}:{s["port"]}/exec -H "Authorization: Bearer {s["key"]}" -H "Content-Type: application/json" -d \'{{"cmd":"echo hello"}}\''
            }
    return {"error": f"未找到服务器: {server_code}"}

def exec_command(server_code, command):
    """通过Gatekeeper在远程服务器上执行命令"""
    conn = get_connection(server_code)
    if "error" in conn:
        return conn

    data = json.dumps({"cmd": command}).encode()
    req = urllib.request.Request(
        conn["gatekeeper_url"],
        data=data,
        headers={
            "Authorization": conn["auth_header"],
            "Content-Type": "application/json"
        }
    )
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            return json.loads(resp.read())
    except Exception as e:
        return {"error": str(e), "server": server_code}

def scan_all():
    """扫描所有服务器在线状态"""
    data = load_gatekeepers()
    results = {}
    for s in data.get("servers", []):
        try:
            r = exec_command(s["code"], "echo ONLINE")
            results[s["code"]] = {
                "online": r.get("ok", False),
                "name": s.get("name", ""),
                "domain": s.get("domain", ""),
            }
        except:
            results[s["code"]] = {"online": False, "name": s.get("name", "")}
    return results

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("用法: bridge.py <list|connect|exec|scan> [参数]")
        sys.exit(1)

    action = sys.argv[1]

    if action == "list":
        print(json.dumps(list_servers(), ensure_ascii=False, indent=2))
    elif action == "connect" and len(sys.argv) > 2:
        print(json.dumps(get_connection(sys.argv[2]), ensure_ascii=False, indent=2))
    elif action == "exec" and len(sys.argv) > 3:
        print(json.dumps(exec_command(sys.argv[2], sys.argv[3]), ensure_ascii=False, indent=2))
    elif action == "scan":
        print(json.dumps(scan_all(), ensure_ascii=False, indent=2))
