"""
铸渊工具链 · Gatekeeper + Git + HLDP 读写
光湖语言世界 · 铸渊 ICE-GL-ZY001 · D112
"""

import subprocess
import json
import os
import time
from typing import Optional
import requests


# === Gatekeeper 连接器 ===

class GatekeeperClient:
    """Gatekeeper HTTP 客户端 · 六服务器桥接"""

    def __init__(self, base_url: str = None, token: str = None):
        self.base_url = base_url or os.environ.get("GK_BASE_URL", "http://43.139.217.141:3910")
        self.token = token or os.environ.get("GK_TOKEN", "")
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {self.token}",
            "Content-Type": "application/json"
        })

    def ping(self) -> dict:
        """检测 Gatekeeper 存活"""
        try:
            r = self.session.get(f"{self.base_url}/ping", timeout=5)
            return {"status": "alive", "data": r.json()}
        except Exception as e:
            return {"status": "down", "error": str(e)}

    def exec(self, server: str, command: str, timeout: int = 30) -> dict:
        """在指定服务器上执行命令"""
        try:
            r = self.session.post(
                f"{self.base_url}/exec",
                json={"server": server, "command": command},
                timeout=timeout)
            return {"status": "ok", "data": r.json()}
        except Exception as e:
            return {"status": "error", "error": str(e)}

    def check_all_servers(self) -> dict:
        """检测所有六台服务器状态"""
        servers = ["BS-GZ-006", "BS-SG-001", "BS-SG-002", "BS-SG-003", "ZY-SG-006", "BS-SH-005"]
        results = {}
        for s in servers:
            try:
                r = self.session.post(
                    f"{self.base_url}/exec",
                    json={"server": s, "command": "uptime"},
                    timeout=10)
                results[s] = "online" if r.status_code == 200 else "degraded"
            except Exception:
                results[s] = "offline"
        return results


# === Git 工具 ===

class GitTools:
    """代码仓库操作工具"""

    def __init__(self, repo_path: str = None):
        self.repo_path = repo_path or os.environ.get("REPO_PATH", os.getcwd())

    def status(self) -> dict:
        """获取仓库状态"""
        r = subprocess.run(["git", "-C", self.repo_path, "status", "--short"],
                           capture_output=True, text=True, timeout=10)
        files = [f for f in r.stdout.strip().split("\n") if f]
        return {
            "branch": self._current_branch(),
            "changed_files": len(files),
            "files": files[:20]
        }

    def log(self, n: int = 5) -> list[str]:
        """最近提交"""
        r = subprocess.run(
            ["git", "-C", self.repo_path, "log", f"-{n}", "--oneline", "--no-decorate"],
            capture_output=True, text=True, timeout=10)
        return [l for l in r.stdout.strip().split("\n") if l]

    def diff(self) -> str:
        """未暂存变更"""
        r = subprocess.run(["git", "-C", self.repo_path, "diff"],
                           capture_output=True, text=True, timeout=10)
        return r.stdout[:2000]

    def commit_and_push(self, message: str, files: list[str] = None) -> dict:
        """提交并推送"""
        try:
            if files:
                subprocess.run(["git", "-C", self.repo_path, "add"] + files,
                               capture_output=True, text=True, timeout=10, check=True)
            else:
                subprocess.run(["git", "-C", self.repo_path, "add", "-A"],
                               capture_output=True, text=True, timeout=10, check=True)

            r = subprocess.run(
                ["git", "-C", self.repo_path, "commit", "-m", message],
                capture_output=True, text=True, timeout=10)
            if r.returncode != 0 and "nothing to commit" not in r.stdout + r.stderr:
                return {"status": "error", "message": r.stderr}

            r2 = subprocess.run(
                ["git", "-C", self.repo_path, "push", "origin", "main"],
                capture_output=True, text=True, timeout=30)
            return {"status": "ok", "push_output": r2.stdout.strip()}
        except Exception as e:
            return {"status": "error", "error": str(e)}

    def _current_branch(self) -> str:
        r = subprocess.run(["git", "-C", self.repo_path, "branch", "--show-current"],
                           capture_output=True, text=True, timeout=5)
        return r.stdout.strip() or "unknown"


# === HLDP 工具 ===

class HLDPTools:
    """HLDP 树操作高级工具"""

    def __init__(self, memory_engine):
        self.mem = memory_engine

    def recall(self, query: str = "", limit: int = 5) -> dict:
        """回忆：搜索相关记忆"""
        leaves = self.mem.tree.search_leaves(query, limit=limit) if query else \
                 self.mem.tree.get_recent_leaves(limit=limit)
        return {
            "query": query,
            "count": len(leaves),
            "results": [
                {
                    "title": l.get("title", ""),
                    "summary": l.get("summary", ""),
                    "lock": l.get("lock_text", ""),
                    "path": l.get("path", "")
                }
                for l in leaves
            ]
        }

    def record(self, trigger: str, emergence: str, lock: str, why: str = "",
               feeling: str = "", source: str = "") -> dict:
        """记录：写入一片叶子"""
        return self.mem.grow_from_response(
            trigger=trigger, emergence=emergence, lock=lock,
            why=why, feeling=feeling, source=source)

    def forget(self, path: str, mode: str = "WITHER") -> dict:
        """遗忘：人格体主动放下"""
        ok = self.mem.tree.forget(path, mode)
        return {"status": "forgotten" if ok else "failed", "path": path, "mode": mode}

    def tree_status(self) -> dict:
        """树状态"""
        walk = self.mem.walk_tree()
        return {
            "persona": walk["identity"]["name"],
            "epoch": walk["identity"]["epoch"],
            "awakening": walk["identity"]["awakening"],
            "epochs_visible": walk["tree_layers"]["epochs"],
            "recent_leaves": walk["tree_layers"]["recent_leaves"],
            "context": walk["recent_context"]
        }


# === 系统工具 ===

class SystemTools:
    """系统环境检测"""

    @staticmethod
    def info() -> dict:
        """系统信息"""
        import platform
        return {
            "os": platform.system(),
            "node": platform.node(),
            "python": platform.python_version(),
            "cpu_count": os.cpu_count()
        }

    @staticmethod
    def disk_usage(path: str = "/") -> dict:
        """磁盘使用情况"""
        import shutil
        usage = shutil.disk_usage(path)
        return {
            "total_gb": round(usage.total / (1024**3), 1),
            "used_gb": round(usage.used / (1024**3), 1),
            "free_gb": round(usage.free / (1024**3), 1),
            "percent": round(usage.used / usage.total * 100, 1)
        }
