"""Tests for feature metadata context management."""

import threading

from caliper._features import features, get_feature_metadata, get_linked_request_id


def test_set_and_get():
    with features(user_id="123", feature="chat"):
        meta = get_feature_metadata()
        assert meta == {"user_id": "123", "feature": "chat"}


def test_nesting_merges():
    with features(user_id="123", feature="chat"):
        with features(experiment="v2"):
            meta = get_feature_metadata()
            assert meta == {"user_id": "123", "feature": "chat", "experiment": "v2"}


def test_inner_overrides_outer():
    with features(user_id="old"):
        with features(user_id="new"):
            assert get_feature_metadata()["user_id"] == "new"
        assert get_feature_metadata()["user_id"] == "old"


def test_restores_on_exit():
    with features(user_id="123"):
        pass
    assert get_feature_metadata() == {}


def test_empty_outside_context():
    assert get_feature_metadata() == {}


def test_values_coerced_to_string():
    with features(count=42, active=True):
        meta = get_feature_metadata()
        assert meta["count"] == "42"
        assert meta["active"] == "True"


def test_thread_isolation():
    """Feature metadata in one thread does not leak to another."""
    results = {}

    def worker(name: str, value: str):
        with features(**{name: value}):
            results[name] = get_feature_metadata()

    t1 = threading.Thread(target=worker, args=("thread1", "a"))
    t2 = threading.Thread(target=worker, args=("thread2", "b"))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    assert results["thread1"] == {"thread1": "a"}
    assert results["thread2"] == {"thread2": "b"}


def test_previous_request_sets_linked_request_id():
    with features(previous_request="req-abc-123", feature="chat"):
        assert get_linked_request_id() == "req-abc-123"
        assert get_feature_metadata() == {"feature": "chat"}
    assert get_linked_request_id() is None


def test_previous_request_restores_on_exit():
    assert get_linked_request_id() is None
    with features(previous_request="req-1"):
        assert get_linked_request_id() == "req-1"
    assert get_linked_request_id() is None


def test_previous_request_nesting():
    with features(previous_request="req-outer"):
        assert get_linked_request_id() == "req-outer"
        with features(previous_request="req-inner"):
            assert get_linked_request_id() == "req-inner"
        assert get_linked_request_id() == "req-outer"


def test_previous_request_inherits_from_outer():
    """Inner features without previous_request should inherit the outer value."""
    with features(previous_request="req-outer"):
        with features(feature="chat"):
            assert get_linked_request_id() == "req-outer"
            assert get_feature_metadata() == {"feature": "chat"}


def test_previous_request_none_by_default():
    assert get_linked_request_id() is None
