"""CUDA availability helpers shared across predictors.

These helpers cache results per process (via functools.lru_cache) to avoid
repeated subprocess calls during model initialization.
"""

import functools
import os
import subprocess  # nosec B404 - static nvidia-smi call used for availability check


@functools.lru_cache(maxsize=1)
def is_nvidia_smi_available() -> bool:
    """Return True if nvidia-smi is available and responds successfully."""
    try:
        # [B603:subprocess_without_shell_equals_true] subprocess call - check for execution of untrusted input.
        # [B607:start_process_with_partial_path] Starting a process with a partial executable path
        subprocess.run(
            ["nvidia-smi"],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            check=True,
        )  # nosec B603, B607
        return True
    except (subprocess.CalledProcessError, FileNotFoundError):
        return False


def resolve_device_id(env_var: str = "HL_GPU_DEVICE_ID", default: int = 0) -> int:
    """Return an integer device id from an env var, falling back to default on errors."""
    raw = os.environ.get(env_var, default)
    try:
        return int(raw)
    except (TypeError, ValueError):
        return int(default)
