"""How much memory this process is holding.

Nothing watched this before. The CMS health page reports the *PHP request's*
peak against PHP's `memory_limit` — accurate, and about a process that lives for
milliseconds and never loads an OCR model. The process that actually holds half
a gigabyte was invisible, and the first symptom of it growing past the machine
would have been a document vanishing mid-read.

WHAT THE NUMBERS MEAN

Measured on 2026-08-03 over two runs: the models cost ~350 MB once, on first
read, and a first pass over a varied set climbs to roughly 545 MB. Reading the
same documents again adds nothing — 31 reads of one document moved RSS by 7 MB,
and the second and third passes over six documents added 14 MB between them.

So the shape to expect is a step up to a ceiling, then flat. **A slow steady
climb is the anomaly**, not the initial jump, and that is why `peak_rss_mb` is
reported alongside the current figure: one sample cannot distinguish "settled at
its ceiling" from "on the way past it".

WHY IT NEVER RAISES

This feeds telemetry. A status report is not worth an outage, and neither is a
memory reading — so every failure path here returns None and the block is simply
omitted. That includes psutil being absent: it is a declared dependency, but an
install that pulls new code without reinstalling must lose this figure rather
than its whole status report.
"""

from __future__ import annotations

import logging
from typing import Any

logger = logging.getLogger(__name__)

_MB = 1024 * 1024

#: Highest RSS seen since this process started, in bytes.
#:
#: Tracked here rather than read from the OS because the portable answer is
#: worse: psutil exposes a peak on Windows (`peak_wset`) and not on Linux, so
#: relying on it would report a high-water mark on one platform and silently
#: omit it on the other. Watching our own samples is the same answer everywhere,
#: at the cost of missing a spike between two reports.
_peak = 0


def reset_peak() -> None:
    """Forget the high-water mark. For tests, which must not inherit each other's."""
    global _peak

    _peak = 0


def usage() -> dict[str, Any]:
    """Current and peak RSS in whole megabytes, or `{}` if it cannot be read."""
    global _peak

    rss = _rss_bytes()

    if rss is None:
        return {}

    _peak = max(_peak, rss)

    return {
        "rss_mb": round(rss / _MB),
        "peak_rss_mb": round(_peak / _MB),
    }


def _rss_bytes() -> int | None:
    """This process's resident set size, or None if it cannot be determined.

    Imported inside the function on purpose. A module-level import would make an
    absent psutil an ImportError at startup for a deployment that is otherwise
    entirely capable of reading documents.
    """
    try:
        import psutil
    except ImportError:
        logger.debug("psutil is not installed; the status report omits memory.")

        return None

    try:
        return int(psutil.Process().memory_info().rss)
    except Exception:  # noqa: BLE001 - telemetry never breaks the caller
        logger.debug("Could not read this process's memory.", exc_info=True)

        return None
