"""샷 경계 = generation_context. 이미 있는 경계를 쓴다."""
import pytest

from app.modules.llm.opik_trace import current_trace


@pytest.fixture
def _fake_client(monkeypatch):
    sent = []

    class _T:
        def __init__(self, **kw):
            sent.append(kw)

        def end(self, **kw):
            pass

        def update(self, **kw):
            pass

    class _C:
        def trace(self, **kw):
            return _T(**kw)

    from app.modules.llm import opik_trace
    monkeypatch.setattr(opik_trace, "_get_client", lambda: _C())
    return sent


@pytest.fixture(autouse=True)
def _v2(monkeypatch):
    from app.core import config
    monkeypatch.setattr(config.settings, "opik_trace_v2_enabled", True)


def test_shot_scope_opens_named_trace(monkeypatch, _fake_client, tmp_path):
    from app.services.image_capture.context import generation_context
    monkeypatch.setenv("PROJECTS_DIR", str(tmp_path))

    with generation_context("proj-1", "ep-1", stage="still_recipe",
                            still_id="abcdef01-2222-3333-4444-555555555555",
                            scene_index=12, shot_index=3):
        h = current_trace()
        assert h is not None
        assert h.name == "still:abcdef01 · still_recipe"
    assert current_trace() is None

    kw = _fake_client[0]
    assert "step:still_recipe" in kw["tags"]
    assert kw["metadata"]["still_id"] == "abcdef01-2222-3333-4444-555555555555"
    assert kw["metadata"]["scene_index"] == 12
    assert kw["metadata"]["shot_index"] == 3
    assert kw["metadata"]["project_id"] == "proj-1"


def test_scope_without_still_id_uses_stage(_fake_client, monkeypatch, tmp_path):
    from app.services.image_capture.context import generation_context
    monkeypatch.setenv("PROJECTS_DIR", str(tmp_path))

    with generation_context("proj-1", "ep-1", stage="background_render"):
        assert current_trace().name == "stage:background_render"


def test_nested_shot_scope_wins(_fake_client, monkeypatch, tmp_path):
    """스텝 trace 안에 샷 trace 가 열리면 안쪽이 부모다."""
    from app.modules.llm.opik_trace import open_trace
    from app.services.image_capture.context import generation_context
    monkeypatch.setenv("PROJECTS_DIR", str(tmp_path))

    with open_trace(name="step:scene_image_pipeline", tags=[], metadata={},
                    thread_id="ep_x") as step_h:
        with generation_context("p", "e", stage="still_recipe",
                                still_id="99999999-0000-0000-0000-000000000000"):
            assert current_trace().uid != step_h.uid
        assert current_trace() is step_h


def test_disabled_opens_nothing(monkeypatch, _fake_client, tmp_path):
    from app.core import config
    from app.services.image_capture.context import generation_context
    monkeypatch.setattr(config.settings, "opik_trace_v2_enabled", False)
    monkeypatch.setenv("PROJECTS_DIR", str(tmp_path))

    with generation_context("p", "e", stage="still_recipe", still_id="x"):
        assert current_trace() is None
    assert _fake_client == []
