#!/usr/bin/env python3
"""
tools_helix.py - Helix Substrate Tool Adapters (WO#GINNIE_03)
==============================================================

First-class Helix substrate tools for Echo Ginnie:
- Healthchecks
- Seed regeneration
- Perf suite
- Gauntlet runs
"""

import json
import subprocess
import time
from pathlib import Path
from typing import Any, Dict, List, Optional

# Helix-CDC root
HELIX_ROOT = Path.home() / "helix-cdc"


def run_healthcheck_quick() -> Dict[str, Any]:
    """
    Quick healthcheck of Helix substrate.

    Returns status of key components.
    """
    results = {
        "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        "checks": {},
    }

    # Check helix_cdc package
    try:
        import helix_cdc
        results["checks"]["helix_cdc_import"] = {"status": "ok"}
    except ImportError as e:
        results["checks"]["helix_cdc_import"] = {"status": "fail", "error": str(e)}

    # Check Jazz package
    try:
        from helix_cdc.jazz import JazzClient, get_cpu_load
        cpu = get_cpu_load()
        results["checks"]["jazz"] = {"status": "ok", "cpu": cpu}
    except ImportError as e:
        results["checks"]["jazz"] = {"status": "fail", "error": str(e)}

    # Check KRISPER bridge
    try:
        from helix_cdc.advanced.bridge.krisper_bridge import KRISPERBridge
        results["checks"]["krisper_bridge"] = {"status": "ok"}
    except ImportError as e:
        results["checks"]["krisper_bridge"] = {"status": "fail", "error": str(e)}

    # Check Makefile exists
    makefile = HELIX_ROOT / "Makefile"
    if makefile.exists():
        results["checks"]["makefile"] = {"status": "ok", "path": str(makefile)}
    else:
        results["checks"]["makefile"] = {"status": "missing"}

    # Check receipts dir
    receipts = HELIX_ROOT / "receipts"
    if receipts.exists():
        receipt_count = len(list(receipts.glob("*.json")))
        results["checks"]["receipts"] = {"status": "ok", "count": receipt_count}
    else:
        results["checks"]["receipts"] = {"status": "missing"}

    # Overall status
    all_ok = all(c.get("status") == "ok" for c in results["checks"].values())
    results["overall"] = "healthy" if all_ok else "degraded"

    return results


def list_seeds() -> Dict[str, Any]:
    """
    List available Helix seeds (.hxz files).
    """
    seed_dirs = [
        HELIX_ROOT / "seeds",
        Path.home() / "seedpack_final_verified/seeds",
        Path.home() / "ORGANIZED/Projects/Echo/ECHO_INTEGRATED_SYSTEM/ai_models/encoded_supermodels",
    ]

    seeds = []
    for d in seed_dirs:
        if d.exists():
            for hxz in d.glob("*.hxz"):
                seeds.append({
                    "name": hxz.stem,
                    "path": str(hxz),
                    "size_bytes": hxz.stat().st_size,
                })

    return {
        "count": len(seeds),
        "seeds": seeds,
    }


def regen_seed(seed_id: str) -> Dict[str, Any]:
    """
    Regenerate from a Helix seed.

    Args:
        seed_id: Seed identifier or path

    Returns:
        Regeneration result
    """
    # Find seed
    seed_path = None
    if Path(seed_id).exists():
        seed_path = Path(seed_id)
    else:
        # Search common locations
        for pattern in [f"*{seed_id}*.hxz", f"{seed_id}.hxz"]:
            for d in [HELIX_ROOT / "seeds", Path.home() / "seedpack_final_verified/seeds"]:
                if d.exists():
                    matches = list(d.glob(pattern))
                    if matches:
                        seed_path = matches[0]
                        break

    if not seed_path or not seed_path.exists():
        return {"status": "error", "message": f"Seed not found: {seed_id}"}

    # Try to regenerate using helix_regen if available
    try:
        from helix_cdc.helix_regen import regenerate_from_seed
        result = regenerate_from_seed(seed_path)
        return {"status": "ok", "seed": str(seed_path), "result": result}
    except ImportError:
        # Fall back to stub
        return {
            "status": "stub",
            "seed": str(seed_path),
            "size_bytes": seed_path.stat().st_size,
            "note": "helix_regen not available - would regenerate here",
        }


def run_perf_suite(quick: bool = True) -> Dict[str, Any]:
    """
    Run Helix performance suite.

    Args:
        quick: If True, run quick smoke tests only
    """
    target = "perf-quick" if quick else "perf-suite"

    try:
        result = subprocess.run(
            ["make", target],
            cwd=str(HELIX_ROOT),
            capture_output=True,
            text=True,
            timeout=300,
        )

        return {
            "status": "ok" if result.returncode == 0 else "fail",
            "target": target,
            "returncode": result.returncode,
            "stdout": result.stdout[-2000:] if result.stdout else "",
            "stderr": result.stderr[-500:] if result.stderr else "",
        }
    except subprocess.TimeoutExpired:
        return {"status": "timeout", "target": target}
    except FileNotFoundError:
        return {"status": "error", "message": "make not found"}


def run_gauntlet() -> Dict[str, Any]:
    """
    Run full Helix gauntlet tests.
    """
    try:
        result = subprocess.run(
            ["make", "gauntlet"],
            cwd=str(HELIX_ROOT),
            capture_output=True,
            text=True,
            timeout=600,
        )

        return {
            "status": "ok" if result.returncode == 0 else "fail",
            "returncode": result.returncode,
            "stdout": result.stdout[-3000:] if result.stdout else "",
            "stderr": result.stderr[-500:] if result.stderr else "",
        }
    except subprocess.TimeoutExpired:
        return {"status": "timeout"}
    except FileNotFoundError:
        return {"status": "error", "message": "make not found"}


def get_jazz_metrics() -> Dict[str, Any]:
    """
    Get current Jazz timing metrics.
    """
    try:
        from helix_cdc.jazz import get_jazz_metrics as _get_metrics, get_cpu_load
        metrics = _get_metrics()
        metrics["current_cpu"] = get_cpu_load()
        return metrics
    except ImportError:
        return {"status": "unavailable", "error": "Jazz module not loaded"}


def list_makefile_targets() -> Dict[str, Any]:
    """
    List available Makefile targets.
    """
    makefile = HELIX_ROOT / "Makefile"
    if not makefile.exists():
        return {"status": "error", "message": "Makefile not found"}

    targets = []
    content = makefile.read_text()
    for line in content.split("\n"):
        if line and not line.startswith("\t") and not line.startswith("#"):
            if ":" in line and not line.startswith("."):
                target = line.split(":")[0].strip()
                if target and not target.startswith("$"):
                    targets.append(target)

    return {
        "count": len(targets),
        "targets": targets[:50],  # Limit
    }


# Tool registry
HELIX_TOOLS = {
    "healthcheck_quick": run_healthcheck_quick,
    "list_seeds": list_seeds,
    "regen_seed": regen_seed,
    "perf_suite": run_perf_suite,
    "gauntlet": run_gauntlet,
    "jazz_metrics": get_jazz_metrics,
    "list_makefile_targets": list_makefile_targets,
}


def get_helix_tool(name: str):
    """Get a Helix tool by name."""
    return HELIX_TOOLS.get(name)


def list_helix_tools() -> List[str]:
    """List available Helix tools."""
    return list(HELIX_TOOLS.keys())
