"""Telemetry helpers for governed tool-output shaping.

Separates observability payload construction/emission from shaping policy so the
PolicyWrappedToolset can stay focused on policy and budget enforcement.
"""

from typing import Any, Callable


# @invar:allow shell_result: Telemetry strategy detector returns strategy string
# @shell_complexity: Strategy detection requires shape-based branching
def detect_tool_output_shaping_strategy(
    original_content: Any,
    shaped_content: Any,
    *,
    effective_budget: int | None = None,
    progressive_metadata_keys: tuple[str, ...],
    truncated_marker: str,
) -> str:
    """Detect which shaping strategy was applied.

    Args:
        original_content: Original tool result before shaping.
        shaped_content: Shaped tool result after budget enforcement.
        effective_budget: Current effective budget for shaping decisions.
        progressive_metadata_keys: Keys indicating source-side pagination metadata.
        truncated_marker: Marker used by text truncation logic.

    Returns:
        Strategy name for telemetry contract fields.
    """
    _ = effective_budget

    if shaped_content == "" and original_content != "":
        return "failsafe_truncated"

    if shaped_content == original_content:
        return "pass_through"

    if isinstance(shaped_content, dict):
        if "summary" in shaped_content or "excerpt" in shaped_content:
            return "summarize_excerpt"
        if any(key in shaped_content for key in progressive_metadata_keys):
            return "progressive_metadata"

    if isinstance(shaped_content, str) and truncated_marker in shaped_content:
        return "truncate_text"

    if isinstance(shaped_content, dict):
        return "budget_shaped"

    if isinstance(shaped_content, str) and original_content != shaped_content:
        return "budget_shaped"

    return "pass_through"


# @invar:allow shell_result: Telemetry payload builder returns bounded dict
def _build_tool_output_shaped_payload(
    *,
    tool_name: str,
    original_size_bytes: int,
    returned_size_bytes: int,
    strategy: str,
    per_call_cap_bytes: int,
    per_turn_consumed_bytes: int,
    source_side_pagination: bool,
) -> dict[str, Any]:
    """Build bounded telemetry payload for tool_output_shaped events."""
    return {
        "event": "tool_output_shaped",
        "tool_name": tool_name,
        "original_size_bytes": original_size_bytes,
        "returned_size_bytes": returned_size_bytes,
        "strategy": strategy,
        "per_call_cap_bytes": per_call_cap_bytes,
        "per_turn_consumed_bytes": per_turn_consumed_bytes,
        "source_side_pagination": source_side_pagination or None,
    }


# @invar:allow shell_result: Telemetry emitter writes logs and returns None
# @shell_orchestration: Assembles and emits bounded telemetry payloads
def emit_tool_output_shaped_telemetry(
    *,
    instance_id: str,
    tool_name: str,
    original_content: Any,
    shaped_content: Any,
    strategy: str,
    per_call_cap_bytes: int,
    per_turn_consumed_bytes: int,
    source_side_pagination: bool,
    content_size_bytes: Callable[[Any], int],
) -> None:
    """Emit tool_output_shaped telemetry with bounded, size-only details.

    Args:
        instance_id: Agent instance ID for persistence location.
        tool_name: Name of the tool that was called.
        original_content: Original tool result before shaping.
        shaped_content: Shaped tool result after budget enforcement.
        strategy: Detected shaping strategy.
        per_call_cap_bytes: Configured per-call cap.
        per_turn_consumed_bytes: Turn budget consumed after shaping.
        source_side_pagination: Whether pagination keys were detected in source.
        content_size_bytes: Size helper used for consistent byte accounting.
    """
    from anima.shell.state import append_log

    payload = _build_tool_output_shaped_payload(
        tool_name=tool_name,
        original_size_bytes=content_size_bytes(original_content),
        returned_size_bytes=content_size_bytes(shaped_content),
        strategy=strategy,
        per_call_cap_bytes=per_call_cap_bytes,
        per_turn_consumed_bytes=per_turn_consumed_bytes,
        source_side_pagination=source_side_pagination,
    )
    append_log(instance_id, "tool_output_shaped", payload)
