"""
Quiet-aware printing and console helpers for BenchBox CLI.

Provides a central place to control user-facing output. When quiet mode is
enabled, all helpers become no-ops and a sink console is returned so that
Rich-based rendering is suppressed.
"""

from __future__ import annotations

import contextlib
import io
import sys
from collections.abc import Iterator
from typing import Any, cast

from rich.console import Console

_QUIET: bool = False
_STD_CONSOLE: Console | None = None
_SINK_CONSOLE: Console | None = None


def set_quiet(enabled: bool) -> None:
    """Globally enable/disable quiet mode for CLI output helpers."""
    global _QUIET
    _QUIET = bool(enabled)


def is_quiet() -> bool:
    """Return True if quiet mode is enabled."""
    return _QUIET


def get_console(quiet: bool | None = None) -> Console:
    """Return a Console that respects quiet mode.

    When quiet is True (or global quiet is enabled), a sink console that
    writes to an in-memory stream is returned so output is discarded.
    """
    q = _QUIET if quiet is None else bool(quiet)
    if not q:
        global _STD_CONSOLE
        if _STD_CONSOLE is None:
            _STD_CONSOLE = Console()
        return cast(Console, _STD_CONSOLE)

    global _SINK_CONSOLE
    if _SINK_CONSOLE is None:
        _SINK_CONSOLE = Console(file=io.StringIO(), stderr=True, force_jupyter=False)
    return cast(Console, _SINK_CONSOLE)


@contextlib.contextmanager
def silence_output(enabled: bool = True) -> Iterator[None]:
    """Context manager to silence stdout and stderr when enabled.

    This suppresses any direct print() calls and third-party console output.
    """
    if not enabled:
        # No-op
        yield
        return

    stdout_backup, stderr_backup = sys.stdout, sys.stderr
    try:
        sys.stdout = io.StringIO()
        sys.stderr = io.StringIO()
        yield
    finally:
        sys.stdout = stdout_backup
        sys.stderr = stderr_backup


def info(msg: str) -> None:
    if _QUIET:
        return
    get_console().print(msg)


class QuietConsoleProxy:
    """Proxy that always forwards to the current quiet-aware Console.

    This class acts as a transparent proxy to a Console object that respects
    quiet mode. It's compatible with Console for type checking purposes.
    """

    def __getattr__(self, item: str) -> Any:  # pragma: no cover - simple delegation
        return getattr(get_console(), item)

    def __enter__(self) -> Console:  # pragma: no cover - context manager support
        """Support context manager protocol by delegating to Console."""
        return get_console().__enter__()

    def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Any:  # pragma: no cover - context manager support
        """Support context manager protocol by delegating to Console."""
        return get_console().__exit__(exc_type, exc_val, exc_tb)

    def __repr__(self) -> str:  # pragma: no cover - debugging helper
        mode = "quiet" if is_quiet() else "verbose"
        return f"<QuietConsoleProxy mode={mode}>"


quiet_console = QuietConsoleProxy()


def warn(msg: str) -> None:
    if _QUIET:
        return
    get_console().print(msg)


def error(msg: str) -> None:
    if _QUIET:
        return
    get_console().print(msg)


def debug(msg: str) -> None:
    if _QUIET:
        return
    get_console().print(msg)


def get_quiet_console() -> Console:
    """Return a sink console regardless of the global quiet flag."""
    return get_console(quiet=True)
