"""Stage-level state-machine emitter for `arborist query`.

Writes one line per state transition to stderr. Stdout stays clean
(JSON output, render output, unfirehose journal) so this is safe to
enable in scripts and pipelines as well as interactively.

Format::

    [arborist  NN.NNs] stage.name key=value key=value

Elapsed is wall-clock seconds since the Progress object was constructed.
The gap *between* lines is the per-stage cost — that's what makes the
slow shard or slow route visible.

Default-on at TTY, default-off when stderr is piped. Override via
``ARBORIST_PROGRESS=1`` (force on) / ``=0`` (force off), or per-call
via ``cli_override="on"|"off"``.
"""

from __future__ import annotations

import os
import sys
import time
from typing import Any


class Progress:
    """Disabled-mode is a true no-op — no string formatting cost."""

    __slots__ = ("enabled", "t_start", "stream")

    def __init__(
        self,
        *,
        enabled: bool,
        t_start: float | None = None,
        stream: Any = None,
    ) -> None:
        self.enabled = enabled
        self.t_start = t_start if t_start is not None else time.monotonic()
        self.stream = stream if stream is not None else sys.stderr

    def emit(self, stage: str, **kv: Any) -> None:
        if not self.enabled:
            return
        elapsed = time.monotonic() - self.t_start
        prefix = f"[arborist {elapsed:6.2f}s] {stage}"
        if kv:
            tail = " ".join(f"{k}={v}" for k, v in kv.items())
            line = f"{prefix} {tail}"
        else:
            line = prefix
        print(line, file=self.stream, flush=True)


_DISABLED = Progress(enabled=False)


def disabled() -> Progress:
    """Singleton no-op emitter, suitable as a default kwarg value."""
    return _DISABLED


def from_env(*, cli_override: str | None = None) -> Progress:
    """Resolve enable-state and return a fresh emitter.

    Precedence: cli_override > ARBORIST_PROGRESS env > TTY auto-detect.
    """
    if cli_override == "on":
        enabled = True
    elif cli_override == "off":
        enabled = False
    else:
        env = (os.environ.get("ARBORIST_PROGRESS") or "").strip().lower()
        if env in ("0", "false", "off", "no"):
            enabled = False
        elif env in ("1", "true", "on", "yes"):
            enabled = True
        else:
            try:
                enabled = sys.stderr.isatty()
            except (AttributeError, ValueError):
                enabled = False
    return Progress(enabled=enabled)
