"""Tagger unit tests. The ONNX model isn't available in CI (it's a 1GB
download into /models), so these test the pure-logic surface:
DEFAULT_STORE_FLOOR constant, SURFACED_CATEGORIES set, TagPrediction
dataclass, and the load()-missing-file error path. Full inference is
exercised by the local integration suite against a real /models volume.
"""

import pytest

from backend.app.services.ml.tagger import (
    DEFAULT_STORE_FLOOR,
    SURFACED_CATEGORIES,
    Tagger,
    TagPrediction,
    get_tagger,
)


def test_surfaced_categories():
    # FC-2d-vii-c: 'artist' retired — artist identity is acquisition-
    # derived (image_record.artist_id), never ML-inferred.
    # 2026-06-01: 'copyright' retired — fandom serves as the franchise/
    # copyright concept; operator doesn't use a separate copyright kind.
    assert SURFACED_CATEGORIES == {"character", "general"}
    assert "artist" not in SURFACED_CATEGORIES
    assert "copyright" not in SURFACED_CATEGORIES


def test_default_store_floor():
    # Raised 0.05 → 0.70 (plan-task #764): the suggestion path filters at
    # 0.70 and the centroid path covers lower-confidence preferred tags, so
    # storing the sub-0.70 tail was redundant (100 GB of TOAST). The live
    # value is DB-backed (ml_settings.tagger_store_floor); this is the default.
    assert DEFAULT_STORE_FLOOR == 0.70


def test_tag_prediction_dataclass():
    p = TagPrediction(name="x", category="general", confidence=0.9)
    assert p.name == "x"
    assert p.category == "general"
    assert p.confidence == 0.9


def test_get_tagger_singleton():
    assert get_tagger() is get_tagger()


def test_load_raises_when_model_missing(tmp_path):
    t = Tagger(model_dir=tmp_path / "nonexistent")
    # Match the trailing "missing at <path>" rather than the specific
    # filename, so a future model-version bump (camie-tagger-v3.onnx, etc.)
    # doesn't bounce this test.
    with pytest.raises(RuntimeError, match=r"\.onnx missing at "):
        t.load()
