#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Briefing working-memory extensions — Items 177, 178, 179.

Kept separate from briefing.py / briefing_ext.py to respect the 300-line ceiling.
  - Item 177: Phonological buffer READ — detect related recent queries for priming context
  - Item 178: Working memory refresh rate READ — alert on high context volatility
  - Item 179: post_shared READ — surface cross-agent shared context items in briefings
"""
import logging

log = logging.getLogger("pulse.brain_query.briefing_wm")


# ---------------------------------------------------------------------------
# Item 177: Phonological buffer READ — query priming from recent queries
# ---------------------------------------------------------------------------
_PHONOLOGICAL_SIMILARITY_THRESHOLD = 0.5  # cosine/jaccard sim above which queries are "related"


def check_phonological_priming(query: str) -> list:
    """Return context lines when the current query is related to recent buffer entries.

    Uses text_similarity to compare current query against the phonological loop
    (recent query texts). Does NOT fire on exact matches (that is habituation,
    handled elsewhere). Only fires on related-but-different queries.

    Args:
        query: Current query string.

    Returns:
        List of "~ CONTEXT: ..." strings (may be empty). Fails open.
    """
    lines: list = []
    try:
        from pulse.brain.memory.working_memory import _PHONOLOGICAL_BUFFER
        if not _PHONOLOGICAL_BUFFER:
            return lines
        from pulse.core.brain_analysis import text_similarity
        q_short = query[:100].strip().lower()
        for fp, data in _PHONOLOGICAL_BUFFER.items():
            try:
                buf_text = data.get("text", "")[:100].lower()
                if not buf_text:
                    continue
                # Skip exact/near-exact matches (habituation handles those)
                if buf_text == q_short:
                    continue
                sim = text_similarity(q_short, buf_text)
                if sim >= _PHONOLOGICAL_SIMILARITY_THRESHOLD:
                    preview = data.get("text", "")[:60].strip()
                    lines.append(f"  ~ CONTEXT: Related to recent query: {preview}")
                    break  # Only report once — highest hit is enough
            except Exception:
                continue
    except Exception as exc:
        log.debug("check_phonological_priming failed: %s", exc)
    return lines


# ---------------------------------------------------------------------------
# Item 178: Working memory refresh rate READ — alert on high volatility
# ---------------------------------------------------------------------------

def check_wm_volatility() -> list:
    """Return a volatility warning when the WM refresh rate is very high.

    High refresh rate = many items are being rapidly evicted, indicating the
    agent is context-switching heavily. Surface this in briefings so the agent
    knows the memory landscape is unstable.

    Returns:
        List containing a "!! HIGH REFRESH RATE: ..." string, or empty list.
        Fails open.
    """
    try:
        from pulse.brain.memory.working_memory_p36 import get_refresh_rate_status
        status = get_refresh_rate_status()
        warning = status.get("warning")
        if warning:
            return [warning]
    except Exception as exc:
        log.debug("check_wm_volatility failed: %s", exc)
    return []


# ---------------------------------------------------------------------------
# Item 179: post_shared READ — surface shared cross-agent context items
# ---------------------------------------------------------------------------
_MAX_SHARED_LINES = 2  # cap lines added to briefing from shared context


def check_shared_context() -> list:
    """Return briefing lines for active cross-agent shared context items.

    Items posted via post_shared() are available to all agents but were never
    surfaced in briefings. This reads the shared context file (TTL-filtered)
    and adds high-priority items to the briefing.

    Returns:
        List of "  ~ SHARED: ..." strings (may be empty). Fails open.
    """
    lines: list = []
    try:
        from pulse.brain.memory.working_memory import _load_shared, _evict_ttl
        data = _load_shared()
        _evict_ttl(data)
        shared_items = data.get("shared_items", [])
        if not shared_items:
            return lines
        # Sort by priority (high > normal > low)
        prio_map = {"high": 3, "normal": 2, "low": 1}
        sorted_items = sorted(
            shared_items,
            key=lambda x: prio_map.get(x.get("priority", "normal"), 2),
            reverse=True,
        )
        for item in sorted_items[:_MAX_SHARED_LINES]:
            text = item.get("text", "")[:80].strip()
            if not text:
                continue
            agent = item.get("posted_by", "?")
            prio = item.get("priority", "normal")
            prefix = "!!" if prio == "high" else "~"
            lines.append(f"  {prefix} SHARED [{agent}]: {text}")
    except Exception as exc:
        log.debug("check_shared_context failed: %s", exc)
    return lines
