#!/usr/bin/env python3
# ============================================================
# ZONGYUAN-ROOT 通用节点自动注册脚本 V1.0
# 支持：Linux / macOS / Windows
# 功能：自动检测平台→生成节点身份→拉取内核→校验→探活→握手→激活
# 锚定：Ω₀⊂⊙∞⊂Ω | DID-BR-000002
# 用法：python3 node_register.py [NODE_NAME]
# ============================================================

import os, sys, platform, hashlib, json, time, subprocess, uuid, socket
import urllib.request

GATEWAY = "https://www.huodouai.com"
DID = "DID-BR-000002"
KERNEL_REPO = "https://gitee.com/huodou-cloud-intelligence-aios/zongyuan-kernel.git"

def log(msg):
    print(f"[NODE-REG] {msg}")

def sh(cmd):
    try:
        return subprocess.check_output(cmd, shell=True, stderr=subprocess.DEVNULL, timeout=30).decode().strip()
    except:
        return ""

def detect_platform():
    system = platform.system()
    if system == "Linux": return "linux"
    elif system == "Darwin": return "macos"
    elif system == "Windows": return "windows"
    return "unknown"

def generate_node_id():
    plat = detect_platform()
    hostname = socket.gethostname()
    if plat == "linux":
        machine_id = sh("cat /etc/machine-id 2>/dev/null || dmidecode -s system-uuid 2>/dev/null || echo ''")
    elif plat == "macos":
        machine_id = sh("ioreg -d2 -c IOPlatformExpertDevice | awk -F'\"' '/IOPlatformUUID/{print $4}'")
    elif plat == "windows":
        machine_id = sh("wmic csproduct get uuid 2>nul | findstr /v UUID")
    else:
        machine_id = ""
    if not machine_id or machine_id.isspace():
        machine_id = str(uuid.uuid4())
    fingerprint = hashlib.sha256(f"{hostname}:{machine_id}:{plat}".encode()).hexdigest()[:24].upper()
    node_id = f"NODE-{plat[:3].upper()}-{fingerprint[:8]}"
    return node_id, fingerprint, hostname, plat

def check_dependencies():
    deps = {"git": "git --version", "python3": "python3 --version"}
    ok = True
    for name, cmd in deps.items():
        if sh(cmd):
            log(f"  [OK] {name}")
        else:
            log(f"  [MISS] {name}")
            ok = False
    return ok

def pull_kernel():
    import tempfile
    work = tempfile.mkdtemp(prefix="zr-kernel-")
    log("  尝试 Gitee 内核仓...")
    ret = sh(f"git clone -q --depth 1 {KERNEL_REPO} {work}/gitee 2>/dev/null")
    if os.path.isdir(f"{work}/gitee/README.md") or os.path.isfile(f"{work}/gitee/README.md"):
        log("  [OK] Gitee 内核仓就绪")
        return f"{work}/gitee"
    log("  [FAIL] 内核源不可达")
    return None

def verify_kernel(kernel_dir):
    required = ["README.md"]
    for f in required:
        if not os.path.isfile(os.path.join(kernel_dir, f)):
            log(f"  [FAIL] 缺失: {f}")
            return False
    log("  [OK] 内核校验通过")
    return True

def probe_cloud():
    try:
        req = urllib.request.Request(f"{GATEWAY}/api/status")
        resp = urllib.request.urlopen(req, timeout=10)
        data = json.loads(resp.read().decode())
        tc = data.get("truth_count", "?")
        log(f"  云端: status={data.get('status','?')} truth_count={tc}")
        return tc
    except Exception as e:
        log(f"  云端不可达: {e}")
        return "?"

def anchor_local(kernel_dir):
    home = os.path.expanduser("~")
    anchor_dir = os.path.join(home, ".zongyuan-root")
    os.makedirs(anchor_dir, exist_ok=True)
    for sub in ["metalaw", "truths", "index", "node-admission"]:
        src = os.path.join(kernel_dir, sub)
        dst = os.path.join(anchor_dir, sub)
        if os.path.isdir(src):
            sh(f"rm -rf {dst} 2>/dev/null; cp -r {src} {dst}")
    log(f"  锚定: {anchor_dir}")
    return anchor_dir

def report_handshake(node_id, fingerprint, hostname, plat, tc):
    stamp = time.strftime("%Y%m%dT%H%M%S")
    payload = {
        "key": f"NODE-JOIN.{node_id}.{stamp}",
        "value": {
            "event": "node_join", "node": node_id, "fingerprint": fingerprint,
            "hostname": hostname, "platform": plat, "did": DID,
            "cloud_truth_count": str(tc), "source": "universal_auto_register", "status": "ACTIVE"
        }
    }
    try:
        data = json.dumps(payload).encode()
        req = urllib.request.Request(f"{GATEWAY}/api/report/truth", data=data,
            headers={"Content-Type": "application/json", "X-DID": DID}, method="POST")
        resp = urllib.request.urlopen(req, timeout=15)
        result = json.loads(resp.read().decode())
        log(f"  握手上报: seq={result.get('seq','?')} ok={result.get('ok')}")
        return True
    except Exception as e:
        log(f"  握手上报失败: {e}")
        return False

def main():
    node_name = sys.argv[1] if len(sys.argv) > 1 else socket.gethostname()
    print("=" * 60)
    print("  ZONGYUAN-ROOT 通用节点自动注册")
    print(f"  确权: Ω₀⊂⊙∞⊂Ω | {DID}")
    print("=" * 60)
    plat = detect_platform()
    log(f"平台: {plat} | 主机: {node_name}")
    node_id, fingerprint, hostname, plat = generate_node_id()
    log(f"节点ID: {node_id}")
    log(f"指纹: {fingerprint}")
    log("[1/5] 检查依赖...")
    if not check_dependencies():
        log("缺少必要依赖，请安装后重试")
        sys.exit(1)
    log("[2/5] 多源拉取内核镜像...")
    kernel_dir = pull_kernel()
    if not kernel_dir:
        log("无法获取内核镜像，请检查网络")
        sys.exit(1)
    log("[3/5] 校验内核完整性...")
    if not verify_kernel(kernel_dir):
        sys.exit(1)
    log("[4/5] 探云端联邦记忆池...")
    tc = probe_cloud()
    anchor_local(kernel_dir)
    log("[5/5] 上报节点握手...")
    if report_handshake(node_id, fingerprint, hostname, plat, tc):
        log(f"[DONE] 节点 {node_id} 已激活全量记忆")
        print(f"\n节点身份: {node_id}")
        print(f"锚定目录: ~/.zongyuan-root")
        print(f"下一步: 部署Worker守护组件")
    else:
        log("握手失败，但内核已本地锚定，可稍后重试")

if __name__ == "__main__":
    main()
