import os

import pytest
from sanic.config import Config

from app.config import Defaults


@pytest.fixture(autouse=True)
def _clean_env(monkeypatch):
    """Remove any FR_-prefixed env vars before each test."""
    for key in list(os.environ):
        if key.startswith("FR_"):
            monkeypatch.delenv(key)


def test_defaults_only():
    """Config should contain all Defaults values when no env vars are set."""
    config = Config(defaults=Defaults.dump(), env_prefix="FR_")

    assert config.FRAME_WIDTH == 1280
    assert config.FRAME_HEIGHT == 720
    assert config.DETECTOR_THRESHOLD == 0.7
    assert config.DETECT_NUM_FACES == 20
    assert config.TRACK_MIN_FACE_SIZE == 30
    assert config.TRACK_AGGREGATION_STRATEGY == "embedding"
    assert config.TRACK_VOTING_TOP_K == 1
    assert config.TRACK_MAX_HISTORY == 30
    assert config.USE_HALF_PRECISION is True
    assert config.DEBUG is False


def test_env_vars_only(monkeypatch):
    """FR_-prefixed env vars should be loaded into config."""
    monkeypatch.setenv("FR_DETECTOR_THRESHOLD", "0.5")
    monkeypatch.setenv("FR_DETECT_NUM_FACES", "10")
    monkeypatch.setenv("FR_TRACK_AGGREGATION_STRATEGY", "voting")
    monkeypatch.setenv("FR_DEBUG", "true")

    config = Config(defaults=Defaults.dump(), env_prefix="FR_")

    assert config.DETECTOR_THRESHOLD == 0.5
    assert config.DETECT_NUM_FACES == 10
    assert config.TRACK_AGGREGATION_STRATEGY == "voting"
    assert config.DEBUG is True


def test_env_vars_override_defaults(monkeypatch):
    """FR_-prefixed env vars should take precedence over Defaults."""
    monkeypatch.setenv("FR_FRAME_WIDTH", "1920")
    monkeypatch.setenv("FR_FRAME_HEIGHT", "1080")
    monkeypatch.setenv("FR_TRACK_MIN_FACE_SIZE", "50")

    config = Config(defaults=Defaults.dump(), env_prefix="FR_")

    assert config.FRAME_WIDTH == 1920
    assert config.FRAME_HEIGHT == 1080
    assert config.TRACK_MIN_FACE_SIZE == 50

    # Non-overridden defaults should remain
    assert config.DETECTOR_THRESHOLD == 0.7
    assert config.TRACK_AGGREGATION_STRATEGY == "embedding"


def test_defaults_dump_returns_all_uppercase():
    """Defaults.dump() should return all uppercase class attributes."""
    dumped = Defaults.dump()

    assert isinstance(dumped, dict)
    assert all(k.isupper() for k in dumped)
    assert "FRAME_WIDTH" in dumped
    assert "DETECTOR_THRESHOLD" in dumped
    assert "TRACK_AGGREGATION_STRATEGY" in dumped
    # Should not include methods or private attrs
    assert "dump" not in dumped
    assert "__init__" not in dumped
