"""Tests for init() and core SDK lifecycle."""

import warnings

import pytest
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider

import pendo_sdk.core as core


@pytest.fixture(autouse=True)
def _reset_sdk():
    """Ensure clean SDK state before and after each test."""
    core.shutdown()
    # Reset the global tracer provider to the default no-op
    trace._TRACER_PROVIDER = None
    trace._TRACER_PROVIDER_SET_ONCE._done = False
    yield
    core.shutdown()
    trace._TRACER_PROVIDER = None
    trace._TRACER_PROVIDER_SET_ONCE._done = False


class TestInit:
    def test_init_sets_global_tracer_provider(self):
        core.init(api_key="test-key", project_id="test-project")

        provider = trace.get_tracer_provider()
        assert isinstance(provider, TracerProvider)

    def test_init_creates_tracer_with_correct_resource(self):
        core.init(api_key="test-key", project_id="my-agent")

        provider = trace.get_tracer_provider()
        resource_attrs = dict(provider.resource.attributes)
        assert resource_attrs["service.name"] == "my-agent"
        assert resource_attrs["pendo.sdk.name"] == "pendo_sdk"
        assert resource_attrs["pendo.sdk.version"] == "0.1.0"

    def test_init_default_project_id(self):
        core.init(api_key="test-key")

        provider = trace.get_tracer_provider()
        assert provider.resource.attributes["service.name"] == "default"

    def test_init_requires_api_key(self):
        with pytest.raises(ValueError, match="api_key is required"):
            core.init(api_key="")

    def test_init_warns_on_duplicate_call(self):
        core.init(api_key="test-key")

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            core.init(api_key="test-key")
            assert len(w) == 1
            assert "already been called" in str(w[0].message)

    def test_init_warns_if_provider_already_set(self):
        # Manually set a non-default provider before init
        existing_provider = TracerProvider()
        trace.set_tracer_provider(existing_provider)

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            core.init(api_key="test-key")
            assert len(w) == 1
            assert "already registered" in str(w[0].message)

    def test_init_stores_visitor_and_account_id(self):
        core.init(
            api_key="test-key",
            visitor_id="visitor-123",
            account_id="account-456",
        )

        assert core.get_visitor_id() == "visitor-123"
        assert core.get_account_id() == "account-456"

    def test_init_identity_defaults_to_none(self):
        core.init(api_key="test-key")

        assert core.get_visitor_id() is None
        assert core.get_account_id() is None


class TestShutdown:
    def test_shutdown_clears_state(self):
        core.init(
            api_key="test-key",
            visitor_id="v1",
            account_id="a1",
        )
        assert core._initialized is True

        core.shutdown()

        assert core._initialized is False
        assert core._provider is None
        assert core._exporter is None
        assert core.get_visitor_id() is None
        assert core.get_account_id() is None

    def test_shutdown_allows_reinit(self):
        core.init(api_key="key-1", project_id="first")
        core.shutdown()

        # Reset the global provider so init can set a new one
        trace._TRACER_PROVIDER = None
        trace._TRACER_PROVIDER_SET_ONCE._done = False

        core.init(api_key="key-2", project_id="second")

        provider = trace.get_tracer_provider()
        assert provider.resource.attributes["service.name"] == "second"

    def test_shutdown_is_safe_when_not_initialized(self):
        core.shutdown()  # Should not raise


class TestGetTracer:
    def test_get_tracer_returns_tracer(self):
        core.init(api_key="test-key")

        tracer = core.get_tracer()
        assert tracer is not None

    def test_get_tracer_custom_name(self):
        core.init(api_key="test-key")

        tracer = core.get_tracer("my-component")
        assert tracer is not None

    def test_get_tracer_creates_working_spans(self):
        core.init(api_key="test-key", project_id="test")

        tracer = core.get_tracer()
        with tracer.start_as_current_span("test-span") as span:
            span.set_attribute("type", "CHAIN")
            assert span.is_recording()


class TestFlush:
    def test_flush_when_initialized(self):
        core.init(api_key="test-key")
        core.flush()  # Should not raise

    def test_flush_when_not_initialized(self):
        core.flush()  # Should not raise
