"""
cortex/hippo/compaction/events.py — Compaction event persistence.
"""

from __future__ import annotations

import json
import logging
from typing import Optional

from cortex.hippo.store.conversation_store import ConversationStore

from .types import CompactionLevel, PassResult

logger = logging.getLogger(__name__)


async def _persist_compaction_events(
    conversation_id: int,
    owner_id: str,
    tokens_before: int,
    tokens_after_leaf: int,
    tokens_after_final: int,
    conversation_store: ConversationStore,
    leaf_result: Optional[PassResult] = None,
    condense_result: Optional[PassResult] = None,
) -> None:
    """Persist compaction event messages for leaf and/or condensed passes.

    Never raises — compaction must not fail due to event persistence.
    """
    if leaf_result is not None:
        await _persist_compaction_event(
            conversation_id=conversation_id,
            owner_id=owner_id,
            pass_type="leaf",
            level=leaf_result.level,
            tokens_before=tokens_before,
            tokens_after=tokens_after_leaf,
            created_summary_id=leaf_result.summary_id,
            condensed_pass_occurred=condense_result is not None,
            conversation_store=conversation_store,
        )
    if condense_result is not None:
        await _persist_compaction_event(
            conversation_id=conversation_id,
            owner_id=owner_id,
            pass_type="condensed",
            level=condense_result.level,
            tokens_before=tokens_after_leaf,
            tokens_after=tokens_after_final,
            created_summary_id=condense_result.summary_id,
            condensed_pass_occurred=True,
            conversation_store=conversation_store,
        )


async def _persist_compaction_event(
    conversation_id: int,
    owner_id: str,
    pass_type: str,
    level: CompactionLevel,
    tokens_before: int,
    tokens_after: int,
    created_summary_id: str,
    condensed_pass_occurred: bool,
    conversation_store: ConversationStore,
) -> None:
    """Write a single compaction event as a role=system message with metadata.

    Never raises — errors are logged and suppressed.
    """
    try:
        content = (
            f"LCM compaction {pass_type} pass ({level}): "
            f"{tokens_before} -> {tokens_after}"
        )
        metadata = json.dumps({
            "type": "compaction_event",
            "pass": pass_type,
            "level": level,
            "tokens_before": tokens_before,
            "tokens_after": tokens_after,
            "created_summary_id": created_summary_id,
            "condensed_pass_occurred": condensed_pass_occurred,
        })
        await conversation_store.create_message(
            conversation_id=conversation_id,
            owner_id=owner_id,
            role="system",
            content=content,
            metadata=metadata,
            token_count=0,  # Don't count event messages toward context budget
        )
    except Exception:
        logger.debug(
            "Failed to persist compaction event (pass=%s, conv=%s)",
            pass_type,
            conversation_id,
            exc_info=True,
        )
