#!/usr/bin/env python3
"""
密钥猎手 · Key Hunter · ICE-GL-ZY-AGT-KEY-001

铸渊叫一声，猎手去找密钥。
不需要铸渊知道密钥在哪里——猎手知道。

用法:
  python3 hunt.py search NOTION_TOKEN        # 搜索指定密钥
  python3 hunt.py list BS-SG-001             # 列出服务器上的密钥
  python3 hunt.py scan-all                    # 扫描所有服务器
"""

import json
import os
import sys
import urllib.request
import base64

# Gatekeeper密钥映射（从brain/gatekeeper-deployment.json加载）
def load_gatekeepers():
    """加载所有Gatekeeper连接信息"""
    repo_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    gk_path = os.path.join(repo_root, "brain", "gatekeeper-deployment.json")
    if os.path.exists(gk_path):
        with open(gk_path) as f:
            data = json.load(f)
        return {s["code"]: s for s in data.get("servers", [])}
    return {}

def gatekeeper_exec(server_code, command, timeout=15):
    """通过Gatekeeper在远程服务器上执行命令"""
    servers = load_gatekeepers()
    if server_code not in servers:
        return {"error": f"未知服务器: {server_code}"}

    srv = servers[server_code]
    url = f"http://{srv['ip']}:{srv['port']}/exec"
    headers = {
        "Authorization": f"Bearer {srv['key']}",
        "Content-Type": "application/json"
    }
    data = json.dumps({"cmd": command}).encode()

    try:
        req = urllib.request.Request(url, data=data, headers=headers)
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return json.loads(resp.read())
    except Exception as e:
        return {"error": str(e)}

def search_key(server_code, key_name):
    """在指定服务器上搜索密钥"""
    # 搜索常见位置
    search_cmd = f"""
    for path in /opt/zhuyuan/guanghulab/.env /opt/juzi/*/.env /etc/environment ~/.gk/secret; do
        if [ -f "$path" ]; then
            result=$(grep -E "^{key_name}=" "$path" 2>/dev/null | head -1)
            if [ -n "$result" ]; then
                echo "FOUND:$path:$result"
            fi
        fi
    done
    # 也搜索PM2环境变量
    pm2 env 0 2>/dev/null | grep "{key_name}=" | head -1 | sed 's/^/FOUND:pm2:/'
    """
    result = gatekeeper_exec(server_code, search_cmd)
    if result.get("ok") and result.get("stdout"):
        for line in result["stdout"].strip().split("\n"):
            if line.startswith("FOUND:"):
                parts = line.split(":", 2)
                return {
                    "found": True,
                    "key_name": key_name,
                    "server": server_code,
                    "location": parts[1] if len(parts) > 1 else "unknown",
                    "value": parts[2].split("=", 1)[1].strip() if len(parts) > 2 and "=" in parts[2] else parts[2] if len(parts) > 2 else "unknown"
                }
    return {"found": False, "key_name": key_name, "server": server_code}

def search_all_servers(key_name, priority_domains=None):
    """在所有服务器上搜索密钥，优先搜索指定域"""
    servers = load_gatekeepers()
    if not priority_domains:
        priority_domains = ["ice-core"]

    results = []

    # 优先搜索ice-core域
    for code, srv in servers.items():
        if srv.get("domain") in priority_domains:
            r = search_key(code, key_name)
            results.append(r)
            if r.get("found"):
                return r  # 找到了就返回

    # 搜索其他域
    for code, srv in servers.items():
        if srv.get("domain") not in priority_domains:
            r = search_key(code, key_name)
            results.append(r)
            if r.get("found"):
                return r

    return {"found": False, "key_name": key_name, "searched": len(results), "results": results}

def list_server_keys(server_code):
    """列出服务器上的所有密钥名称"""
    result = gatekeeper_exec(server_code, """
    for path in /opt/zhuyuan/guanghulab/.env /opt/juzi/*/.env 2>/dev/null; do
        if [ -f "$path" ]; then
            echo "=== $path ==="
            grep -E '^[A-Z_]+=' "$path" | cut -d'=' -f1
        fi
    done
    """)
    if result.get("ok"):
        return {"server": server_code, "output": result.get("stdout", "")}
    return {"server": server_code, "error": result.get("error", "unknown")}

def scan_all():
    """扫描所有服务器状态"""
    servers = load_gatekeepers()
    results = {}
    for code in servers:
        result = gatekeeper_exec(code, "echo ONLINE && hostname")
        results[code] = {
            "online": result.get("ok", False),
            "hostname": result.get("stdout", "").strip() if result.get("ok") else "OFFLINE"
        }
    return results

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

    action = sys.argv[1]

    if action == "search" and len(sys.argv) > 2:
        key_name = sys.argv[2]
        result = search_all_servers(key_name)
        print(json.dumps(result, ensure_ascii=False, indent=2))

    elif action == "list" and len(sys.argv) > 2:
        result = list_server_keys(sys.argv[2])
        print(json.dumps(result, ensure_ascii=False, indent=2))

    elif action == "scan-all":
        result = scan_all()
        print(json.dumps(result, ensure_ascii=False, indent=2))

    else:
        print("未知操作")
