"""Backend ASR via onnx-asr : modèles NVIDIA Parakeet / Canary / Nemotron en ONNX.

Multilingue (FR), léger (~600M), rapide en CPU ; GPU AMD possible via
onnxruntime-rocm. Modèle et execution providers pilotés par la config :

    [voice]
    asr_engine = "onnx"
    onnx_model = "nemo-parakeet-tdt-0.6b-v3"     # multilingue (FR)
    onnx_providers = ["CPUExecutionProvider"]    # ou ["ROCMExecutionProvider", "CPUExecutionProvider"]

Dépendances hors du core (install légère) — voir l'extra `stt[onnx]` ou
`pipx inject stt onnx-asr onnxruntime`.
"""

from __future__ import annotations

from typing import Any

_INSTALL_HINT = (
    "Backend ASR 'onnx' indisponible : onnx-asr / onnxruntime ne sont pas installés.\n"
    "  pipx inject stt onnx-asr onnxruntime         # CPU\n"
    "  pipx inject stt onnx-asr onnxruntime-rocm    # GPU AMD (ROCm)\n"
    "ou réinstalle avec l'extra : pipx install 'stt[onnx]'"
)

DEFAULT_MODEL = "nemo-parakeet-tdt-0.6b-v3"


class OnnxAsrBackend:
    def __init__(self, cfg: dict[str, Any]):
        self.cfg = cfg
        self._model = None

    def _providers(self):
        # onnx-asr accepte des str ("CPUExecutionProvider") ou des tuples (name, options).
        provs = self.cfg.get("onnx_providers") or ["CPUExecutionProvider"]
        return [p if isinstance(p, (list, tuple)) else (p, {}) for p in provs]

    def load(self) -> None:
        try:
            import onnx_asr
        except ImportError as e:  # message actionnable plutôt qu'un ImportError brut
            raise RuntimeError(_INSTALL_HINT) from e
        self._model = onnx_asr.load_model(
            self.cfg.get("onnx_model", DEFAULT_MODEL),
            providers=self._providers(),
        )

    def transcribe(self, audio_int16) -> str:
        import numpy as np

        audio_f32 = audio_int16.astype(np.float32) / 32768.0
        lang = self.cfg.get("language", "fr")
        # Les modèles multilingues acceptent `language=` ; les mono-langue non →
        # on retombe sur l'appel sans langue plutôt que de planter.
        try:
            text = self._model.recognize(audio_f32, language=lang)
        except TypeError:
            text = self._model.recognize(audio_f32)
        return (text or "").strip()
