#!/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 hashlib
import json
import re
import subprocess
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,
    ANTI_PATTERNS_DIR,
)

CONSTITUTION = CONSTITUTION_FILE
ASOP = PROTOCOL_DIR / "ASOP.md"
ANTI_PATTERNS = ANTI_PATTERNS_DIR / "anti_patterns_active.json"


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

try:
    from pulse.brain.integrity.self_check import check_and_warn as _self_check_warn
except Exception:
    _self_check_warn = lambda text: ""

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


def _sha256_file(path: Path) -> str:
    """Return hex SHA-256 of file contents, or 'missing' if not found."""
    if not path.exists():
        return "missing"
    digest = hashlib.sha256(path.read_bytes()).hexdigest()
    return digest[:16] + "..."  # truncated for readability


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 ""





# ── 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("results", {}).get("anti_patterns", [])
    if ap:
        lines.append("|  WARNINGS (from brain):" + " " * 26 + "|")
        for warning in ap[:3]:
            w = (warning.get("text") or warning.get("title") or warning.get("content") or str(warning))[:46]
            lines.append(f"|  ! {w:<47}|")
        lines.append("+" + "-" * 50 + "+")

    knowledge = brain_results.get("results", {}).get("facts", [])
    if knowledge:
        lines.append("|  RELEVANT KNOWLEDGE:" + " " * 29 + "|")
        for k in knowledge[:4]:
            k_text = (k.get("text") or k.get("title") or k.get("content") or str(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:
    """Inject compact governance summary into agent boot context (~200 tokens)."""
    parts = []
    parts.append("=" * 60)
    parts.append("GOVERNANCE CONTEXT (Non-Negotiable — Summary)")
    parts.append("=" * 60)
    parts.append("")

    # Constitution: read file for integrity hash, emit compact summary only
    const_text = _read_file(CONSTITUTION)
    const_hash = _sha256_file(CONSTITUTION)
    if const_text:
        parts.append("## CONSTITUTION (summary)")
        parts.append(
            "4 Tier-0 immutables: Ahimsa, Sovereignty, Veracity, Consensus. "
            "+ 10 Sacred Laws govern all agent behavior."
        )
        parts.append(f"Full text: Corpus_Callosum/CONSTITUTION.md  [sha256: {const_hash}]")
        parts.append("")

    # ASOP: same treatment
    asop_text = _read_file(ASOP)
    asop_hash = _sha256_file(ASOP)
    if asop_text:
        parts.append("## ASOP PROTOCOL (summary)")
        parts.append("7 rules for task coordination: claim, execute, save, no duplication.")
        parts.append(f"Full text: Corpus_Callosum/Protocols/ASOP.md  [sha256: {asop_hash}]")
        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("")

    # P2-5: Agent-agnostic cognitive rules — injected into ALL agent boot contexts
    parts.append("## [RULE:PREDICTION_AWARENESS]")
    parts.append("Before irreversible changes (deploy, delete, migrate), check prediction alerts.")
    parts.append("")

    parts.append("## [RULE:SOURCE_GROUNDING]")
    parts.append("Prefer [CONFIRMED] knowledge over [CONVERSATIONAL]. When contradicting confirmed knowledge, state the conflict explicitly.")
    parts.append("")

    result = chr(10).join(parts)
    # Self-referential check: warn if governance text contains incorrect PULSE claims
    _sc_warn = _self_check_warn(result)
    if _sc_warn:
        result = _sc_warn + chr(10) + result
    return result


