"""Tests for Annotation dataclass and request ID ContextVar."""

import threading
import uuid

from caliper._annotation import (
    Annotation,
    generate_request_id,
    get_last_request_id,
    set_last_request_id,
)


def test_annotation_to_dict():
    annotation = Annotation(
        request_id="abc-123",
        timestamp="2026-02-20T10:00:00+00:00",
        metadata={"sentiment": "positive"},
    )
    d = annotation.to_dict()
    assert d == {
        "request_id": "abc-123",
        "timestamp": "2026-02-20T10:00:00+00:00",
        "metadata": {"sentiment": "positive"},
    }


def test_annotation_to_dict_empty_metadata():
    annotation = Annotation(request_id="abc-123", timestamp="2026-02-20T10:00:00+00:00")
    d = annotation.to_dict()
    assert d["metadata"] == {}


def test_generate_request_id_is_valid_uuid4():
    rid = generate_request_id()
    parsed = uuid.UUID(rid)
    assert parsed.version == 4


def test_generate_request_id_is_unique():
    ids = {generate_request_id() for _ in range(100)}
    assert len(ids) == 100


def test_set_get_last_request_id_roundtrip():
    set_last_request_id("test-id-123")
    assert get_last_request_id() == "test-id-123"


def test_get_last_request_id_default_is_none():
    # ContextVar default is None, but previous tests may have set it.
    # We test that the function returns a string or None (not an error).
    result = get_last_request_id()
    assert result is None or isinstance(result, str)


def test_context_var_thread_isolation():
    """ContextVar should not leak between threads."""
    set_last_request_id("main-thread-id")
    child_saw: list[str | None] = []

    def child():
        child_saw.append(get_last_request_id())

    t = threading.Thread(target=child)
    t.start()
    t.join()

    # Child thread should see None (ContextVar default), not the main thread's value
    assert child_saw[0] is None
