"""Flag-gating tests: ENABLE_CODE_REVIEW off skips code, drawing_integrity runs.

Runner-level smoke tests using stubbed agents (same pattern as
test_wave5b_suppression). Verifies the code/ADA wave is skipped when
ENABLE_CODE_REVIEW is false and the Drawing Integrity wave feeds findings
into the report by_stage counters.
"""

import backend.agents.runner as runner_mod
from backend import config
from backend.agents.base import AgentResult
from backend.agents.runner import run_agent_pipeline


def _stub_agent(artifacts):
    return lambda usage: type("S", (), {
        "name": "stub",
        "run": lambda self, scope: AgentResult(
            scope_id=scope.scope_id, artifacts=list(artifacts)),
    })()


def _integrity_finding():
    return {
        "issue_id": "DI-1", "severity": "high", "confidence": "high",
        "source_stage": "drawing_integrity", "sheets": ["A101"],
        "category": "dangling_reference",
        "description": "Detail callout 5/A101 has no detail 5 on this sheet",
        "evidence": [{"sheet": "A101", "source_text": "5/A101"}],
    }


def _patch(monkeypatch, code_should_raise):
    monkeypatch.setattr(
        runner_mod, "convert_pdf_to_images",
        lambda path: [{"page_number": 1, "base64": "QUJD"}])
    # Sheet has 3+ assertions so the integrity wave does NOT skip it.
    monkeypatch.setattr(runner_mod, "SheetExtractorAgent", _stub_agent([
        {"sheet_number": "A101", "page_number": 1, "level": "1",
         "discipline": "A", "assertions": [
             {"text": "5/A101", "object_type": "detail_marker"},
             {"text": "ROOM 101", "object_type": "room"},
             {"text": "DOOR 101A", "object_type": "door"},
         ]},
    ]))
    monkeypatch.setattr(runner_mod, "SheetIndexAgent", _stub_agent([{}]))
    monkeypatch.setattr(runner_mod, "JurisdictionAgent", _stub_agent([{}]))
    monkeypatch.setattr(runner_mod, "LinkerAgent", _stub_agent([]))
    monkeypatch.setattr(runner_mod, "ConflictCriticAgent", _stub_agent([]))

    def code_boom(usage):
        if code_should_raise:
            raise AssertionError("CodeAgent must not run when gated off")
        return _stub_agent([])(usage)
    monkeypatch.setattr(runner_mod, "CodeAgent", code_boom)

    monkeypatch.setattr(runner_mod, "DrawingIntegrityAgent",
                        _stub_agent([_integrity_finding()]))
    monkeypatch.setattr(runner_mod, "ConstructabilityAgent", _stub_agent([]))
    monkeypatch.setattr(runner_mod, "CompletenessAgent", _stub_agent([]))
    monkeypatch.setattr(
        runner_mod, "BrainAgent",
        lambda usage: type("B", (), {
            "run": lambda self, findings, si, ju: (list(findings), []),
            "plan_clarifications": lambda self, prioritized: []})())
    # Stub the wave-5b verifier so the high-severity integrity finding is
    # confirmed (never a live network call).
    monkeypatch.setattr(
        "backend.agents.verifier.call_json",
        lambda **kwargs: {"verdicts": [
            {"sheet": "A101", "source_text": "5/A101",
             "verdict": "confirmed", "actual_text": None, "notes": None},
        ]})


def test_code_gated_off_integrity_on(monkeypatch, tmp_path):
    monkeypatch.setattr(config, "ENABLE_CODE_REVIEW", False)
    monkeypatch.setattr(config, "ENABLE_DRAWING_INTEGRITY", True)
    _patch(monkeypatch, code_should_raise=True)
    pdf = tmp_path / "d.pdf"
    pdf.write_bytes(b"%PDF-1.4\n")
    report = run_agent_pipeline(str(pdf), out_dir=str(tmp_path),
                                require_review=False)
    by_stage = report["summary"]["by_stage"]
    assert by_stage["code"] == 0
    assert by_stage["drawing_integrity"] == 1
    # The integrity finding survived into the validated set.
    assert any(f.get("issue_id") == "DI-1"
               for f in report.get("validated_issues") or [])


def test_code_enabled_runs(monkeypatch, tmp_path):
    monkeypatch.setattr(config, "ENABLE_CODE_REVIEW", True)
    monkeypatch.setattr(config, "ENABLE_DRAWING_INTEGRITY", True)
    _patch(monkeypatch, code_should_raise=False)
    # build_code_scopes runs on the real sheet; CodeAgent is stubbed to []
    pdf = tmp_path / "d.pdf"
    pdf.write_bytes(b"%PDF-1.4\n")
    report = run_agent_pipeline(str(pdf), out_dir=str(tmp_path),
                                require_review=False)
    # No crash; integrity still reported.
    assert report["summary"]["by_stage"]["drawing_integrity"] == 1
