#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
Boot Formatting: Utility helpers and display builders for boot context.

Contains file reading, recency tagging, heading cleanup, status card,
governance context, and recent activity — split from boot_briefing.py
for Law 7 compliance.

Dependencies: Python stdlib + brain_utils (internal)
"""

import json
import re
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path

# ── Path constants ──────────────────────────────────────────────────
from pulse.core.brain_utils import (
    HIPPOCAMPUS_DIR, ROOT_DIR, CONSTITUTION_FILE, PROTOCOL_DIR,
)

CONSTITUTION = CONSTITUTION_FILE
ASOP = PROTOCOL_DIR / "ASOP.md"
ANTI_PATTERNS = HIPPOCAMPUS_DIR / "Patterns" / "anti_patterns.md"


# ── Utility helpers ─────────────────────────────────────────────────

def _read_file(path: Path) -> str:
    if not path.exists():
        return ""
    return path.read_text(encoding="utf-8", errors="replace").strip()


def _recency_tag(text: str) -> str:
    """Recency tag from embedded date: [today], [2d ago], etc."""
    date_match = re.search(r"(\d{4}-\d{2}-\d{2})", text)
    if not date_match:
        return ""
    try:
        entry_date = datetime.strptime(date_match.group(1), "%Y-%m-%d").replace(tzinfo=timezone.utc)
        delta = (datetime.now(timezone.utc) - entry_date).days
        if delta <= 0:
            return "[today]"
        elif delta == 1:
            return "[1d ago]"
        elif delta <= 6:
            return f"[{delta}d ago]"
        elif delta <= 13:
            return "[1w ago]"
        elif delta <= 30:
            return f"[{delta // 7}w ago]"
        else:
            return f"[{delta}d]"
    except (ValueError, TypeError):
        return ""


def _clean_brain_headings(headings: list, limit: int = 10) -> list:
    """Deduplicate and filter brain headings for quality."""
    seen = set()
    clean = []
    for h in headings:
        h = h.strip().lstrip("*").strip()
        if len(h) < 15:
            continue
        if h.startswith("/") or h.startswith("\\") or h.startswith("C:"):
            continue
        key = h.lower()[:40]
        if key not in seen:
            seen.add(key)
            clean.append(h[:80])
    return clean[-limit:]


def _load_md_headings(path: Path, limit: int = 10) -> list:
    """Read an .md file and return cleaned ## headings."""
    if not path.exists():
        return []
    text = path.read_text(encoding="utf-8", errors="replace")
    headings = re.findall(r"^## (.+)$", text, re.MULTILINE)
    return _clean_brain_headings(headings, limit=limit)


def _extract_search_hits(hits: list, limit: int = 5) -> list:
    """Extract text snippets from brain_search hit dicts."""
    out = []
    for h in hits[:limit]:
        text = (h.get("text") or h.get("title", ""))[:80].strip()
        if text and len(text) > 10:
            out.append(text)
    return out


# ── Display builders ────────────────────────────────────────────────

def build_status_card(agent_name: str, tier: str, task: dict,
                      brain_results: dict) -> str:
    """Build the standardized status card."""
    task_display = task.get("title", "NONE — waiting for tasks")[:40] if task else "NONE — waiting for tasks"
    task_id = task.get("id", "") if task else ""
    status = "WORKING" if task else "IDLE"
    id_suffix = f" ({task_id})" if task_id else ""

    lines = [""]
    lines.append("+" + "=" * 50 + "+")
    lines.append("|  PULSE SWARM — Agent Online" + " " * 22 + "|")
    lines.append("+" + "=" * 50 + "+")
    lines.append(f"|  Agent:   {agent_name:<40}|")
    lines.append(f"|  Tier:    {tier:<40}|")
    lines.append(f"|  Task:    {task_display}{id_suffix}"[:51].ljust(51) + "|")
    lines.append(f"|  Status:  {status:<40}|")
    lines.append("+" + "-" * 50 + "+")

    ap = brain_results.get("anti_patterns", [])
    if ap:
        lines.append("|  WARNINGS (from brain):" + " " * 26 + "|")
        for warning in ap[:3]:
            w = warning[:46]
            lines.append(f"|  ! {w:<47}|")
        lines.append("+" + "-" * 50 + "+")

    knowledge = brain_results.get("knowledge", [])
    if knowledge:
        lines.append("|  RELEVANT KNOWLEDGE:" + " " * 29 + "|")
        for k in knowledge[:4]:
            k_text = k[:46]
            lines.append(f"|  * {k_text:<47}|")
        lines.append("+" + "-" * 50 + "+")

    lines.append("")
    return "\n".join(lines)


def _load_profile_hint() -> str:
    """Load user profile and return a one-line behavior hint for agents."""
    try:
        from pulse.core.user_profile import UserProfile
        p = UserProfile.load()
        hints = []
        if p.preferred_verbosity and p.preferred_verbosity != "normal":
            hints.append(f"verbosity={p.preferred_verbosity}")
        if p.communication_style and p.communication_style != "concise":
            hints.append(f"style={p.communication_style}")
        if p.dont_wants:
            hints.append(f"DONT: {', '.join(p.dont_wants[:5])}")
        return f"User prefs: {'; '.join(hints)}" if hints else ""
    except Exception:
        return ""


def build_governance_context() -> str:
    """Load full Constitution + Laws for injection into agent context."""
    parts = []
    parts.append("=" * 60)
    parts.append("GOVERNANCE CONTEXT (Non-Negotiable — Full Text)")
    parts.append("=" * 60)
    parts.append("")

    const_text = _read_file(CONSTITUTION)
    if const_text:
        parts.append("## CONSTITUTION")
        parts.append(const_text)
        parts.append("")

    asop_text = _read_file(ASOP)
    if asop_text:
        parts.append("## ASOP PROTOCOL (Agent Self-Organization)")
        parts.append(asop_text)
        parts.append("")

    # User profile preferences
    profile_hint = _load_profile_hint()
    if profile_hint:
        parts.append(f"## USER PROFILE\n{profile_hint}\n")

    # Brain-first enforcement for all agents (critical for non-hooked agents like Codex)
    parts.append("## BRAIN-FIRST ENFORCEMENT (Mandatory)")
    parts.append("CRITICAL: Before EVERY write_file or edit_file call, you MUST run:")
    parts.append("  python pulse/brain/brain_query.py --query \"<what you are writing>\"")
    parts.append("Apply the brain's knowledge to avoid repeating past failures.")
    parts.append("This is a Tier 0 governance requirement — not optional.")
    parts.append("")

    return "\n".join(parts)


# ── Activity loader ─────────────────────────────────────────────────

def load_recent_activity(limit: int = 5) -> list:
    """Load recent session activity + git commits."""
    activity = []

    sessions_file = HIPPOCAMPUS_DIR / "Evidence" / "Sessions" / "agent_sessions.json"
    if sessions_file.exists():
        try:
            sessions = json.loads(sessions_file.read_text(encoding="utf-8"))
            if isinstance(sessions, list):
                for s in sessions[-limit:]:
                    agent = s.get("agent", "unknown").upper()
                    ts = s.get("timestamp", "")
                    tag = _recency_tag(ts)
                    learnings = s.get("learnings", [])
                    summary = learnings[0][:60] if learnings else s.get("task", "session")
                    activity.append(f"{agent} {tag}: {summary}")
        except Exception:
            pass

    try:
        result = subprocess.run(
            ["git", "log", f"--max-count={limit}", "--format=%ar|%s"],
            capture_output=True, text=True, timeout=5,
            cwd=str(ROOT_DIR),
        )
        if result.returncode == 0:
            for line in result.stdout.strip().splitlines():
                if "|" in line:
                    ago, msg = line.split("|", 1)
                    activity.append(f"GIT [{ago}]: {msg[:60]}")
    except Exception:
        pass

    return activity[-limit:]
