import pytest
from unittest.mock import MagicMock, patch
from app.core.applicability import _if_background_mode, APPLICABILITY_VALIDATORS


def test_if_background_mode_off_returns_false():
    runner = MagicMock()
    with patch("app.core.config.settings.background_mode", "off"):
        assert _if_background_mode(runner) is False


def test_if_background_mode_on_returns_true():
    runner = MagicMock()
    with patch("app.core.config.settings.background_mode", "on"):
        assert _if_background_mode(runner) is True


def test_if_background_mode_legacy_alias_returns_true():
    """floor_plan_anchored은 legacy alias로 'on' 동등."""
    runner = MagicMock()
    with patch("app.core.config.settings.background_mode", "floor_plan_anchored"):
        assert _if_background_mode(runner) is True


def test_validator_registered():
    assert "if_background_mode" in APPLICABILITY_VALIDATORS


# ── W21B E2E 실측: _StubRunner(db 없음) 경유 _if_planning_doc 오판 fix ──


def test_if_planning_doc_stub_runner_without_db_uses_own_session(monkeypatch):
    """_StubRunner 는 db 속성이 없다 — runner.db 직접 접근이 AttributeError →
    fallback False 로 ★항상 not_applicable 오판★ 하던 결함. db=None 전달로
    project_has_planning_doc 이 자체 세션 판정하게 한다 (E2E warning 3건 실측)."""
    from app.core.applicability import _if_planning_doc, _StubRunner

    calls = {}

    def fake_has_doc(project_id, db=None):
        calls["project_id"] = project_id
        calls["db"] = db
        return True

    import app.services.planning_doc_analysis_service as svc
    monkeypatch.setattr(svc, "project_has_planning_doc", fake_has_doc)

    stub = _StubRunner(step_id="planning_doc_analysis", project_id="p1",
                       episode_id="e1", manifest={})
    assert _if_planning_doc(stub) is True          # fallback False 가 아니라 실제 판정
    assert calls == {"project_id": "p1", "db": None}


def test_if_planning_doc_real_runner_passes_db(monkeypatch):
    """db 를 가진 runner 는 기존대로 그 세션을 전달 (동작 보존)."""
    from app.core.applicability import _if_planning_doc

    calls = {}

    def fake_has_doc(project_id, db=None):
        calls["db"] = db
        return False

    import app.services.planning_doc_analysis_service as svc
    monkeypatch.setattr(svc, "project_has_planning_doc", fake_has_doc)

    class _R:
        project_id = "p1"
        db = "SENTINEL_DB"

    assert _if_planning_doc(_R()) is False
    assert calls["db"] == "SENTINEL_DB"
