"""tests/dev7/test_circuit_breaker.py — Circuit Breaker (task-2367 P1)"""
import json
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parents[2]))


@pytest.fixture
def cb_workspace(tmp_path, monkeypatch):
    (tmp_path / "memory" / "audit").mkdir(parents=True)
    monkeypatch.setenv("WORKSPACE_ROOT", str(tmp_path))
    # dispatch.py에서 함수만 추출 (전체 import는 외부 의존성 때문에 실패할 수 있음)
    # 대신 함수 정의를 직접 가져오기 위해 import
    import importlib.util
    spec = importlib.util.spec_from_file_location(
        "dispatch",
        str(Path(__file__).resolve().parents[2] / "dispatch.py"),
    )
    try:
        d = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(d)
        return tmp_path, d
    except Exception:
        # dispatch.py import 실패 시: 함수만 직접 추출
        pytest.skip("dispatch.py import 실패 (외부 의존성)")


def test_no_violation_passes(cb_workspace):
    workspace, d = cb_workspace
    allowed, reason = d._check_circuit_breaker("dev7", workspace_root=str(workspace))
    assert allowed is True


def test_three_violations_blocks(cb_workspace):
    workspace, d = cb_workspace
    # 3회 위반 누적
    for i in range(3):
        d._record_violation("dev7", f"task-test-{i}", "test violation", workspace_root=str(workspace))
    allowed, reason = d._check_circuit_breaker("dev7", workspace_root=str(workspace))
    assert allowed is False
    assert "circuit breaker OPEN" in reason or "violations" in reason


def test_record_violation_persists(cb_workspace):
    workspace, d = cb_workspace
    d._record_violation("dev7", "task-x", "scope violation", workspace_root=str(workspace))
    vc_file = workspace / "memory" / "audit" / "violation-count.json"
    data = json.loads(vc_file.read_text())
    assert data["dev7"]["count"] == 1
    assert len(data["dev7"]["history"]) == 1
    assert data["dev7"]["history"][0]["task_id"] == "task-x"


def test_independent_bots(cb_workspace):
    """bot별로 카운트 독립."""
    workspace, d = cb_workspace
    d._record_violation("dev1", "t1", "v", workspace_root=str(workspace))
    d._record_violation("dev1", "t2", "v", workspace_root=str(workspace))
    d._record_violation("dev1", "t3", "v", workspace_root=str(workspace))

    allowed_dev1, _ = d._check_circuit_breaker("dev1", workspace_root=str(workspace))
    allowed_dev2, _ = d._check_circuit_breaker("dev2", workspace_root=str(workspace))

    assert allowed_dev1 is False
    assert allowed_dev2 is True
