"""Miscellaneous helpers for the voice loop runtime."""

from __future__ import annotations

import logging
import sys


def _suppress_mcp_noise() -> None:
    """Quiet down noisy MCP/Agno loggers during voice mode.

    Sets specific loggers to WARNING so the terminal stays clean
    for the voice transcript.
    """
    for name in (
        "mcp",
        "mcp.server",
        "mcp.client",
        "agno",
        "agno.mcp",
        "httpx",
        "httpcore",
    ):
        logging.getLogger(name).setLevel(logging.WARNING)


def _install_quiet_asyncgen_hooks() -> None:
    """Silence MCP stdio_client async-generator teardown noise.

    When the voice loop exits, Python GC finalizes Agno's MCP
    stdio_client async generators. anyio's cancel-scope teardown
    prints ugly tracebacks to stderr. These are harmless — the
    MCP subprocesses die with the loop. We intercept them here.
    """
    _orig_hook = getattr(sys, "unraisablehook", None)

    def _quiet_hook(args):
        # Swallow RuntimeError from anyio cancel-scope teardown
        # and BaseExceptionGroup from MCP stdio_client generators
        if args.exc_type in (RuntimeError, BaseExceptionGroup):
            msg = str(args.exc_value) if args.exc_value else ""
            if "cancel scope" in msg or "unhandled errors" in msg:
                return
        # Also swallow GeneratorExit from stdio_client
        if args.exc_type is GeneratorExit:
            return
        # Everything else: forward to original hook
        if _orig_hook:
            _orig_hook(args)
        else:
            sys.__unraisablehook__(args)

    sys.unraisablehook = _quiet_hook
