#!/usr/bin/env python3
"""
atlas_autonomy_export.py - Expose autonomy loop state via JSON for live dashboard.

Reads:
  - autonomy_queue.json (pending/completed)
  - autonomy_loop.log (last 50 lines)
  - vault/00_Atlas_Wiki/_autonomy/*.md (last 20 outputs)

Writes:
  - atlas-autonomy.json — consumed by Atlas Command AUTONOMY tab

Runs: every 1 min via Atlas-Autonomy-Export schtask (lightweight).
"""
import json
import sys
import subprocess
from pathlib import Path
from datetime import datetime

import io
if sys.stdout.encoding != 'utf-8':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')

QUEUE = Path(r"C:\Users\Gebruiker\.config\atlas\autonomy_queue.json")
LOG = Path(r"C:\Users\Gebruiker\.config\atlas\autonomy_loop.log")
AUTO = Path(r"C:\Users\Gebruiker\MEGA\Atlas Corporation\00_Atlas_Wiki\_autonomy")
OUT = Path(r"C:\Users\Gebruiker\AppData\Local\Atlas\analyses\atlas-autonomy.json")
SSH = "root@<YOUR_VPS_IP>"
REMOTE = "/opt/atlas/dashboard/atlas-autonomy.json"


def parse_frontmatter(text):
    """Extract simple YAML frontmatter (between --- markers)."""
    if not text.startswith("---"):
        return {}, text
    end = text.find("---", 3)
    if end == -1:
        return {}, text
    yaml_block = text[3:end].strip()
    body = text[end+3:].strip()
    fm = {}
    for line in yaml_block.split("\n"):
        if ":" in line:
            k, v = line.split(":", 1)
            fm[k.strip()] = v.strip()
    return fm, body


def main():
    state = {
        "generated_at": datetime.now().isoformat(timespec="seconds"),
        "loop_running": False,
        "queue_pending": 0,
        "queue_completed": 0,
        "log_tail": [],
        "recent_outputs": [],
        "next_fire": None,
        "task_state": None,
    }

    # Queue
    if QUEUE.exists():
        try:
            q = json.loads(QUEUE.read_text(encoding="utf-8"))
            state["queue_pending"] = len(q.get("pending", []))
            state["queue_completed"] = len(q.get("completed", []))
            if q.get("completed"):
                last = q["completed"][-1]
                state["last_completed"] = {
                    "topic": last.get("topic"),
                    "node": last.get("node"),
                    "model": last.get("model"),
                    "completed_at": last.get("completed_at"),
                    "elapsed_s": last.get("elapsed_s"),
                }
        except Exception as e:
            state["queue_err"] = str(e)[:100]

    # Log tail
    if LOG.exists():
        try:
            lines = LOG.read_text(encoding="utf-8", errors="replace").splitlines()
            state["log_tail"] = lines[-50:]
        except Exception:
            pass

    # Schtask state
    try:
        r = subprocess.run(
            ["powershell.exe", "-NoProfile", "-Command",
             "$t=Get-ScheduledTask -TaskName Atlas-Autonomy-Hourly -ErrorAction SilentlyContinue;"
             "if ($t) { $i=Get-ScheduledTaskInfo $t; "
             "Write-Output ('STATE:' + $t.State + '|LAST:' + $i.LastRunTime + '|NEXT:' + $i.NextRunTime + '|RESULT:' + $i.LastTaskResult) }"],
            capture_output=True, text=True, timeout=10
        )
        out = r.stdout.strip()
        if out.startswith("STATE:"):
            parts = dict(p.split(":", 1) for p in out[6:].split("|"))
            state["task_state"] = "STATE:" + out[6:]
            state["loop_running"] = (parts.get("STATE") != "Disabled")
            state["next_fire"] = parts.get("NEXT")
    except Exception as e:
        state["task_state_err"] = str(e)[:100]

    # Recent outputs (last 20 by mtime)
    if AUTO.exists():
        try:
            md_files = sorted(AUTO.glob("*.md"), key=lambda p: p.stat().st_mtime, reverse=True)[:20]
            for p in md_files:
                try:
                    text = p.read_text(encoding="utf-8", errors="replace")
                    fm, body = parse_frontmatter(text)
                    state["recent_outputs"].append({
                        "filename": p.name,
                        "mtime": datetime.fromtimestamp(p.stat().st_mtime).isoformat(timespec="seconds"),
                        "topic": fm.get("topic", "?"),
                        "node": fm.get("node", "?"),
                        "model": fm.get("model", "?"),
                        "elapsed_s": fm.get("elapsed_s", "?"),
                        "polish_status": fm.get("polish_status", "?"),
                        "body_preview": body[:400].replace("\n", " ").strip(),
                    })
                except Exception:
                    pass
        except Exception as e:
            state["outputs_err"] = str(e)[:100]

    state["recent_output_count"] = len(state["recent_outputs"])

    OUT.parent.mkdir(parents=True, exist_ok=True)
    OUT.write_text(json.dumps(state, indent=2, ensure_ascii=False), encoding="utf-8")
    print(f"wrote {OUT}")
    print(f"  pending={state['queue_pending']} completed={state['queue_completed']} outputs={state['recent_output_count']}")
    try:
        subprocess.run(["scp", str(OUT), f"{SSH}:{REMOTE}"], check=True, timeout=20)
        print(f"pushed to {SSH}:{REMOTE}")
    except Exception as e:
        print(f"scp fail: {e}")


if __name__ == "__main__":
    main()
