"""Tests for the LLM span filter."""

from opentelemetry.sdk.trace import ReadableSpan

from flowlines._filter import is_llm_span


def _make_span(
    attributes: dict[str, str | bool | int | float] | None = None,
) -> ReadableSpan:
    """Create a ReadableSpan with the given attributes."""
    return ReadableSpan(name="test-span", attributes=attributes)


class TestIsLlmSpan:
    def test_gen_ai_attribute(self) -> None:
        span = _make_span({"gen_ai.system": "openai", "gen_ai.request.model": "gpt-4"})
        assert is_llm_span(span) is True

    def test_ai_dot_attribute(self) -> None:
        span = _make_span({"ai.pipeline.name": "my-pipeline"})
        assert is_llm_span(span) is True

    def test_no_llm_attributes(self) -> None:
        span = _make_span({"http.method": "GET", "http.url": "https://example.com"})
        assert is_llm_span(span) is False

    def test_empty_attributes(self) -> None:
        span = _make_span({})
        assert is_llm_span(span) is False

    def test_none_attributes(self) -> None:
        span = _make_span(None)
        assert is_llm_span(span) is False

    def test_ai_without_dot(self) -> None:
        """'ai' without a dot should not match."""
        span = _make_span({"ai": "value"})
        assert is_llm_span(span) is False

    def test_aix_prefix(self) -> None:
        """'aix.foo' should not match — only 'ai.' prefix counts."""
        span = _make_span({"aix.foo": "bar"})
        assert is_llm_span(span) is False

    def test_mixed_attributes(self) -> None:
        """A span with both LLM and non-LLM attributes should return True."""
        span = _make_span(
            {
                "http.method": "POST",
                "gen_ai.system": "openai",
                "custom.tag": "value",
            }
        )
        assert is_llm_span(span) is True
