"""Performance pins for ``mgf.hrb.fmt`` — PR-* test plan T6.

The fmt helpers are called inside hot operator-facing render paths
in both the CLI (via ``mgf-hrb cli doctor``) and the Qt GUI (via
``DoctorViewModel`` populating the doctor pane on every poll
tick). If a "small refactor" accidentally introduces a per-call
allocation, regex compile, or stdlib-call into one of them, the
operator-perceived UI smoothness degrades silently.

Budgets (p99 over 50k iter after 1k warmup):

  format_uptime               < 1 µs   (current measured: ~150 ns)
  format_duration             < 1 µs   (current measured: ~140 ns)
  format_rss                  < 1 µs   (current measured: ~240 ns)
  format_severity_glyph       < 1 µs   (current measured: ~125 ns)
  import mgf.hrb.fmt cold     < 5 ms   (current measured: ~160 µs)

The 1 µs budget gives ~5x slack over current measurements for
hardware variance + future defensive code. If a helper crosses
the budget the failure message names the regression specifically
so the contributor can target the slowdown without re-running
profiling. Nightly-only via the ``perf`` marker.
"""

from __future__ import annotations

import importlib
import sys
import time
from typing import TYPE_CHECKING

import pytest

if TYPE_CHECKING:
    from collections.abc import Callable

from mgf.hrb.fmt import (
    format_duration,
    format_rss,
    format_severity_glyph,
    format_uptime,
)

pytestmark = pytest.mark.perf

_WARMUP = 1_000
_MEASUREMENTS = 50_000
_BUDGET_NS = 1_000  # 1 µs per call


def _p99_ns(fn: Callable[[], None]) -> int:
    """Run `fn` `_MEASUREMENTS` times after a warmup, return the
    p99 of per-call duration in nanoseconds.

    Uses time.perf_counter_ns for monotonic, sub-µs-resolution
    measurement. p99 (not mean / median) is the right shape for a
    UI-budget pin: an occasional outlier is fine; consistent
    slowdown isn't.
    """
    # Warmup — fills the CPython opcode cache + the JIT-equivalent
    # interpreter dispatch table. Without it, the first calls
    # measure interpreter startup, not steady-state.
    for _ in range(_WARMUP):
        fn()
    samples: list[int] = []
    for _ in range(_MEASUREMENTS):
        t0 = time.perf_counter_ns()
        fn()
        samples.append(time.perf_counter_ns() - t0)
    samples.sort()
    return samples[int(len(samples) * 0.99)]


def test_format_uptime_p99_under_1us() -> None:
    p99 = _p99_ns(lambda: format_uptime(3_725_000))  # "1h 2m 5s" path
    assert p99 < _BUDGET_NS, (
        f"format_uptime p99 = {p99} ns; budget = {_BUDGET_NS} ns. "
        "A regression has slowed the hot-path render — the most "
        "common operator-visible UI tick path."
    )


def test_format_duration_p99_under_1us() -> None:
    p99 = _p99_ns(lambda: format_duration(1_200_000))  # ms→s band path
    assert p99 < _BUDGET_NS, f"format_duration p99 = {p99} ns; budget = {_BUDGET_NS} ns."


def test_format_rss_p99_under_1us() -> None:
    p99 = _p99_ns(lambda: format_rss(44_400_000))  # MiB band — common
    assert p99 < _BUDGET_NS, f"format_rss p99 = {p99} ns; budget = {_BUDGET_NS} ns."


def test_format_severity_glyph_p99_under_1us() -> None:
    p99 = _p99_ns(lambda: format_severity_glyph("fail"))
    assert p99 < _BUDGET_NS, f"format_severity_glyph p99 = {p99} ns; budget = {_BUDGET_NS} ns."


def test_fmt_module_cold_import_under_5ms() -> None:
    """Cold-import budget. fmt is imported by hrb-app's view layer
    + the CLI doctor command + (eventually) every UI consumer in
    the federation. A slow cold-import slows app startup."""
    # Evict the module so we measure a true cold import.
    for mod in [m for m in list(sys.modules) if m == "mgf.hrb.fmt"]:
        del sys.modules[mod]
    t0 = time.perf_counter_ns()
    importlib.import_module("mgf.hrb.fmt")
    elapsed_us = (time.perf_counter_ns() - t0) / 1000
    assert elapsed_us < 5_000, (  # 5 ms = 5000 µs
        f"mgf.hrb.fmt cold import took {elapsed_us:.0f} µs; "
        f"budget = 5000 µs. Something heavy was added to module top."
    )
