"""Tests fail-close P0-1 : le moteur ne doit JAMAIS être invoqué si CamemBERT-bio
est indisponible et que use_local_ner=True.

Garantie de sécurité : EngineUnavailableError est levée AVANT l'appel du moteur,
ce qui empêche la production d'un document potentiellement non anonymisé.
"""

from pathlib import Path

import pytest

from gui_v6.engine_bridge import (
    EngineSettings,
    EngineUnavailableError,
    NerManagers,
    make_process_fn,
)


def _managers_with_broken_camembert(settings):
    def boom():
        raise RuntimeError("model.onnx absent")

    return NerManagers(
        settings,
        factories={"camembert": boom, "eds": boom, "gliner": boom},
        caps_provider=lambda: {},
    )


def test_process_fn_raises_when_mandatory_ner_unavailable():
    settings = EngineSettings(use_local_ner=True)
    managers = _managers_with_broken_camembert(settings)
    called = {"engine": False}

    def fake_engine(*a, **k):
        called["engine"] = True
        return {"pdf": "x"}

    fn = make_process_fn(settings, managers=managers, engine=fake_engine)
    with pytest.raises(EngineUnavailableError):
        fn(Path("doc.pdf"), Path("/tmp/out"))
    assert called["engine"] is False


def test_process_fn_runs_when_ner_ok():
    settings = EngineSettings(use_local_ner=True)
    managers = NerManagers(
        settings,
        factories={"camembert": lambda: object(), "eds": lambda: None, "gliner": lambda: None},
        caps_provider=lambda: {},
    )
    fn = make_process_fn(settings, managers=managers, engine=lambda *a, **k: {"pdf": "ok"})
    assert fn(Path("d.pdf"), Path("/tmp/out")) == {"pdf": "ok"}


def test_process_fn_skips_ner_guard_when_local_ner_disabled():
    # use_local_ner=False : on ne charge pas le NER et on NE bloque PAS,
    # même si les factories échoueraient (symétrique du garde-fou fail-close).
    settings = EngineSettings(use_local_ner=False)
    managers = _managers_with_broken_camembert(settings)
    fn = make_process_fn(settings, managers=managers, engine=lambda *a, **k: {"pdf": "ok"})
    assert fn(Path("d.pdf"), Path("/tmp/out")) == {"pdf": "ok"}
