#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""System status command: orchestrator, daemons, task board, evidence."""
from __future__ import annotations

import json
from datetime import datetime, timezone

from pulse.cli import ROOT_DIR, STATE_DIR, TASK_BOARD, EVIDENCE_DIR
from pulse.core.brain_utils import (read_jsonl_entries, LESSONS_JSONL, FAILS_JSONL,
                                     PATTERNS_JSONL, ANTI_PATTERNS_DIR, INTENTS_DIR)
from pulse.tasks.task_ops import (
    is_process_running, load_json, load_worker_pids,
    PID_FILE, DAEMON_PIDS,
)


def cmd_status():
    """Show system status: orchestrator, daemons, task board, evidence."""
    print("=" * 55)
    print("  PULSE Status")
    print("=" * 55)

    from pulse.cli.status._license_display import show_license_status
    show_license_status()
    # Orchestrator
    orch_pid = None
    orch_running = False
    if PID_FILE.exists():
        try:
            orch_pid = int(PID_FILE.read_text().strip())
            orch_running = is_process_running(orch_pid)
        except Exception:
            pass
    print(f"\n  Orchestrator:  {'RUNNING (PID ' + str(orch_pid) + ')' if orch_running else 'STOPPED'}")

    # Daemons
    daemon_pids = []
    if DAEMON_PIDS.exists():
        try:
            daemon_pids = json.loads(DAEMON_PIDS.read_text())
        except Exception:
            pass
    alive = [p for p in daemon_pids if is_process_running(p)]
    dead = [p for p in daemon_pids if not is_process_running(p)]
    print(f"  Daemons:       {len(alive)} alive" + (f", {len(dead)} dead" if dead else ""))

    # Daemon Death Alerts
    daemon_alerts_file = STATE_DIR / "daemon_alerts.json"
    if daemon_alerts_file.exists():
        try:
            daemon_alerts = json.loads(daemon_alerts_file.read_text(encoding="utf-8"))
            if daemon_alerts:
                print(f"  Daemon Alerts:  {len(daemon_alerts)} dead daemon(s)")
                for alert in daemon_alerts[-5:]:
                    name = alert.get("label") or alert.get("daemon", "?")
                    ts = alert.get("timestamp", "")[:19]
                    exit_code = alert.get("exit_code", "?")
                    print(f"    DEAD: {name} (exit={exit_code}) at {ts}")
        except Exception:
            pass

    # Task Board
    board = load_json(TASK_BOARD)
    dispatches = board.get("dispatches", [])
    tasks_open = tasks_claimed = tasks_done = tasks_total = 0
    for d in dispatches:
        for t in d.get("tasks", []):
            tasks_total += 1
            s = t.get("status", "")
            if s == "open":
                tasks_open += 1
            elif s == "claimed":
                tasks_claimed += 1
            elif s in ("done", "completed", "archived"):
                tasks_done += 1

    print(f"\n  Task Board:")
    if tasks_total == 0:
        print("    (empty)")
    else:
        print(f"    {tasks_open} open | {tasks_claimed} claimed | {tasks_done} done | {tasks_total} total")

    for d in dispatches:
        for t in d.get("tasks", []):
            if t.get("status") == "open":
                tier = t.get("recommended_tier", "standard")
                print(f"    -> [{tier}] {t.get('title', '?')}")

    # Evidence
    evidence_count = 0
    if EVIDENCE_DIR.exists():
        for f in EVIDENCE_DIR.iterdir():
            if f.suffix == ".json":
                try:
                    d = json.loads(f.read_text(encoding="utf-8"))
                    if isinstance(d, list):
                        evidence_count += len(d)
                except Exception:
                    pass
    print(f"\n  Brain Evidence: {evidence_count} items")

    # Brain Health
    brain_stats = {}
    try:
        from pulse.core.brain_db import get_conn
        _conn = get_conn()
        brain_stats["wants"] = _conn.execute("SELECT COUNT(*) FROM intents WHERE type='want'").fetchone()[0]
        brain_stats["dont_wants"] = _conn.execute("SELECT COUNT(*) FROM intents WHERE type='dont_want'").fetchone()[0]
        brain_stats["anti_patterns"] = _conn.execute("SELECT COUNT(*) FROM anti_patterns").fetchone()[0]
    except Exception:
        brain_stats.setdefault("wants", 0)
        brain_stats.setdefault("dont_wants", 0)
        brain_stats.setdefault("anti_patterns", 0)
    for label, jsonl_path in [
        ("lessons", LESSONS_JSONL),
        ("fails", FAILS_JSONL),
        ("patterns", PATTERNS_JSONL),
    ]:
        try:
            brain_stats[label] = len(read_jsonl_entries(jsonl_path))
        except Exception:
            brain_stats[label] = 0

    decisions_path = EVIDENCE_DIR / "Decisions" / "auto_decisions.json"
    if decisions_path.exists():
        try:
            data = json.loads(decisions_path.read_text(encoding="utf-8"))
            brain_stats["decisions"] = len(data.get("decisions", [])) if isinstance(data, dict) else 0
        except Exception:
            brain_stats["decisions"] = 0

    schemas_count = proc_count = 0
    for _lbl, _p, _k in [("schemas", ROOT_DIR / "Hippocampus" / "Patterns" / "schemas.json", "schemas"),
                          ("procedures", EVIDENCE_DIR / "Metrics" / "procedural_log.json", "procedures")]:
        if _p.exists():
            try:
                _d = json.loads(_p.read_text(encoding="utf-8"))
                val = len(_d.get(_k, [])) if isinstance(_d, dict) else 0
                if _lbl == "schemas":
                    schemas_count = val
                else:
                    proc_count = val
            except Exception:
                pass

    total_knowledge = (brain_stats.get("lessons", 0) + brain_stats.get("fails", 0) +
                       brain_stats.get("patterns", 0) + brain_stats.get("decisions", 0))
    extraction_rate = (total_knowledge / evidence_count * 100) if evidence_count > 0 else 0

    print(f"  Brain Health:  {brain_stats.get('wants', 0)} wants | "
          f"{brain_stats.get('dont_wants', 0)} dont_wants | "
          f"{brain_stats.get('anti_patterns', 0)} anti-patterns")
    print(f"  Knowledge:     {brain_stats.get('lessons', 0)} lessons | "
          f"{brain_stats.get('fails', 0)} fails | "
          f"{brain_stats.get('patterns', 0)} patterns | "
          f"{brain_stats.get('decisions', 0)} decisions")
    print(f"  Schemas:       {schemas_count} proven | {proc_count} procedures")
    print(f"  Extraction:    {total_knowledge} items ({extraction_rate:.1f}% of {evidence_count} evidence)")

    # Last Capture
    capture_state = STATE_DIR / "auto_capture_state.json"
    if capture_state.exists():
        try:
            cs = json.loads(capture_state.read_text(encoding="utf-8"))
            last_batch = cs.get("last_log_batch", "")
            if last_batch:
                print(f"  Last Capture:  {last_batch[:19]}")
        except Exception:
            pass

    # Epistemic Forager (D9)
    forager_state = STATE_DIR / "epistemic_forager_state.json"
    if forager_state.exists():
        try:
            fs = json.loads(forager_state.read_text(encoding="utf-8"))
            v = fs.get("verdicts", {})
            last = (fs.get("last_run") or "never")[:19]
            print(f"  Forager (D9):  {fs.get('runs', 0)} runs | "
                  f"confirm={v.get('confirm', 0)} update={v.get('update', 0)} "
                  f"prune={v.get('prune', 0)} | last={last}")
        except Exception:
            pass

    # Skill Tracking (D10 feed)
    skill_usage = STATE_DIR / "skill_usage.json"
    if skill_usage.exists():
        try:
            su = json.loads(skill_usage.read_text(encoding="utf-8"))
            total_uses = sum(v.get("uses", 0) for v in su.values())
            print(f"  Skills (D10):  {len(su)} tracked | {total_uses} total uses")
        except Exception:
            pass

    # Ghost Resonance (D11)
    ghost_state = STATE_DIR / "ghost_resonance_state.json"
    if ghost_state.exists():
        try:
            gs = json.loads(ghost_state.read_text(encoding="utf-8"))
            last_g = (gs.get("last_run") or "never")[:19]
            print(f"  Ghost (D11):   {gs.get('total_ghosts', 0)} ghosts | "
                  f"{gs.get('total_procedures', 0)} procedures | last={last_g}")
        except Exception:
            pass

    # Hebbian Balancer (D12)
    hebbian_state = STATE_DIR / "hebbian_matrix.json"
    if hebbian_state.exists():
        try:
            hs = json.loads(hebbian_state.read_text(encoding="utf-8"))
            last_h = (hs.get("last_sweep") or "never")[:19]
            n_models = len(hs.get("matrix", {}))
            n_obs = len(hs.get("processed_tasks", []))
            print(f"  Hebbian (D12): {n_models} models | {n_obs} outcomes | last={last_h}")
        except Exception:
            pass

    # Homeostatic Scheduler (D13)
    homeostatic_state = STATE_DIR / "homeostatic_state.json"
    if homeostatic_state.exists():
        try:
            hs = json.loads(homeostatic_state.read_text(encoding="utf-8"))
            last_h = (hs.get("last_run") or "never")[:19]
            stress = hs.get("stress", 0.0)
            zone = hs.get("zone", "unknown")
            n_over = hs.get("active_overrides", 0)
            print(f"  Homeostatic (D13): stress={stress:.2f} ({zone}) | "
                  f"{n_over} overrides | last={last_h}")
        except Exception:
            pass

    # Procedural Sleep Healer (D14)
    _h14 = STATE_DIR / "healer_state.json"
    if _h14.exists():
        try:
            hs14 = json.loads(_h14.read_text(encoding="utf-8"))
            sw = hs14.get("last_sweep", {})
            print(f"  Healer (D14):  strip={sw.get('stripped', {}).get('stripped', 0)} "
                  f"taint={sw.get('tainted', {}).get('tainted', 0)} "
                  f"promote={sw.get('promoted', {}).get('promoted', 0)} | "
                  f"last={(hs14.get('last_run') or 'never')[:19]}")
        except Exception:
            pass

    # Reflex Arc
    _rx = ANTI_PATTERNS_DIR / "reflex_patterns.json"
    if _rx.exists():
        try:
            _rxd = json.loads(_rx.read_text(encoding="utf-8"))
            _rxs = _rxd.get("stats", {})
            _act = sum(1 for e in _rxd.get("entries", []) if e.get("status") == "active")
            print(f"  Reflex Arc:    {_act} active | {_rxs.get('total', 0)} total | "
                  f"last={(_rxs.get('last_detection') or 'never')[:19]}")
        except Exception:
            pass

    # Pipeline
    pipeline = ROOT_DIR / "Personal_Plans" / "PIPELINE.md"
    if pipeline.exists():
        print("  Pipeline:      Personal_Plans/PIPELINE.md")

    # Workers
    worker_records = load_worker_pids()
    if worker_records:
        alive_w = [r for r in worker_records if is_process_running(r.get("pid", 0))]
        dead_w = len(worker_records) - len(alive_w)
        print(f"\n  Workers:       {len(alive_w)} alive" + (f", {dead_w} dead" if dead_w else ""))
        for r in worker_records:
            tag = "RUNNING" if is_process_running(r.get("pid", 0)) else "DEAD"
            mode_s = "CLI" if "cli" in r.get("mode", "headless") else "API"
            print(f"    {r.get('id', '?'):<28} {tag:<8} [{r.get('tier', '?')}] {mode_s}")
    else:
        print("\n  Workers:       (none)")

    # Live Swarm Heartbeats
    hb_dir = STATE_DIR / "heartbeats"
    if hb_dir.exists():
        active_hbs = []
        for hb_file in hb_dir.iterdir():
            if hb_file.suffix == ".json":
                try:
                    hb = json.loads(hb_file.read_text(encoding="utf-8"))
                    ts = hb.get("timestamp", "")
                    if ts:
                        hb_time = datetime.fromisoformat(ts.replace("Z", "+00:00"))
                        if (datetime.now(timezone.utc) - hb_time).total_seconds() < 300:
                            active_hbs.append(hb)
                except Exception:
                    pass
        if active_hbs:
            print(f"\n  Live Swarm Activity:")
            for hb in sorted(active_hbs, key=lambda x: x.get("agent_id", "")):
                st = hb.get("status", "idle")
                tid = hb.get("current_task_id")
                tf = f" -> {tid}" + (f" (iter {hb['iteration']})" if hb.get("iteration") else "") if st == "working" and tid else ""
                print(f"    {hb.get('agent_id', '?'):<20} [{st.upper()}]{tf}")

    print(f"\n{'=' * 55}\n  pulse start|stop|post|status|swarm|claude|gemini\n{'=' * 55}")
