#!/usr/bin/env python3
"""Wake-up Protocol — session start context injection.

Generates 300-900 tokens of context when a new Hermes session starts.
Loads identity, recent palace context, and fleet status.

Refs: Epic #367, Sub-issue #372
"""

from __future__ import annotations

import json
import os
import subprocess
import time
from pathlib import Path

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------

IDENTITY_PATH = Path.home() / ".mempalace" / "identity.txt"
MEMPALACE_BIN = "/Library/Frameworks/Python.framework/Versions/3.12/bin/mempalace"
FLEET_STATUS_PATH = Path.home() / ".hermes" / "fleet_status.json"
WAKEUP_CACHE_PATH = Path.home() / ".hermes" / "last_wakeup.txt"
WAKEUP_CACHE_TTL = 300  # 5 minutes — don't regenerate if recent


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _load_identity() -> str:
    """Read the agent identity file."""
    try:
        if IDENTITY_PATH.exists():
            text = IDENTITY_PATH.read_text(encoding="utf-8").strip()
            # Cap at ~150 tokens for wake-up brevity
            words = text.split()
            if len(words) > 150:
                text = " ".join(words[:150]) + "..."
            return text
    except (OSError, PermissionError):
        pass
    return ""


def _palace_context() -> str:
    """Run mempalace wake-up command for recent context. Degrades gracefully."""
    try:
        bin_path = MEMPALACE_BIN if os.path.exists(MEMPALACE_BIN) else "mempalace"
        result = subprocess.run(
            [bin_path, "wake-up"],
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0 and result.stdout.strip():
            return result.stdout.strip()
    except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
        # ONNX issues (#373) or CLI not available — degrade gracefully
        pass
    return ""


def fleet_status_summary() -> str:
    """Read cached fleet status for lightweight session context."""
    try:
        if FLEET_STATUS_PATH.exists():
            data = json.loads(FLEET_STATUS_PATH.read_text(encoding="utf-8"))
            lines = ["## Fleet Status"]

            if isinstance(data, dict):
                for agent, status in data.items():
                    if isinstance(status, dict):
                        state = status.get("state", "unknown")
                        last_seen = status.get("last_seen", "?")
                        lines.append(f"  {agent}: {state} (last: {last_seen})")
                    else:
                        lines.append(f"  {agent}: {status}")

            if len(lines) > 1:
                return "\n".join(lines)
    except (OSError, json.JSONDecodeError):
        pass
    return ""


def _check_cache() -> str:
    """Return cached wake-up if fresh enough."""
    try:
        if WAKEUP_CACHE_PATH.exists():
            age = time.time() - WAKEUP_CACHE_PATH.stat().st_mtime
            if age < WAKEUP_CACHE_TTL:
                return WAKEUP_CACHE_PATH.read_text(encoding="utf-8").strip()
    except OSError:
        pass
    return ""


def _write_cache(content: str) -> None:
    """Cache the wake-up content."""
    try:
        WAKEUP_CACHE_PATH.parent.mkdir(parents=True, exist_ok=True)
        WAKEUP_CACHE_PATH.write_text(content, encoding="utf-8")
    except OSError:
        pass


# ---------------------------------------------------------------------------
# Main entry point
# ---------------------------------------------------------------------------

def palace_wakeup(force: bool = False) -> str:
    """Generate wake-up context for a new session. ~300-900 tokens.

    Args:
        force: If True, bypass the 5-minute cache and regenerate.

    Returns:
        Formatted context string suitable for prepending to the system prompt.
    """
    # Check cache first (avoids redundant work on rapid session restarts)
    if not force:
        cached = _check_cache()
        if cached:
            return cached

    parts = []

    # L0: Identity
    identity = _load_identity()
    if identity:
        parts.append(f"## Identity\n{identity}")

    # L1: Recent palace context
    palace = _palace_context()
    if palace:
        parts.append(palace)

    # Fleet status (lightweight)
    fleet = fleet_status_summary()
    if fleet:
        parts.append(fleet)

    # Timestamp
    parts.append(f"## Session\nWake-up generated: {time.strftime('%Y-%m-%d %H:%M:%S')}")

    content = "\n\n".join(parts)

    # Cache for TTL
    _write_cache(content)

    return content


# ---------------------------------------------------------------------------
# CLI entry point for testing
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    print(palace_wakeup(force=True))
