"""
Tests for SDK public interface.

Reference: docs/plans/plan_technical_cleanup_v1.md (Phase P1)
"""

import pytest
import warnings


class TestTypeExports:
    """Verify type exports are available."""
    
    @pytest.mark.unit
    def test_initialization_status_type(self):
        """InitializationStatus TypedDict is exported."""
        from swisper_studio_sdk import InitializationStatus
        
        # Verify it's a TypedDict by checking __annotations__
        assert hasattr(InitializationStatus, '__annotations__')
        assert 'enabled' in InitializationStatus.__annotations__
        assert 'initialized' in InitializationStatus.__annotations__
    
    @pytest.mark.unit
    def test_auto_trace_status_type(self):
        """AutoTraceStatus TypedDict is exported."""
        from swisper_studio_sdk import AutoTraceStatus
        
        assert hasattr(AutoTraceStatus, '__annotations__')
        assert 'langgraph_patched' in AutoTraceStatus.__annotations__
        assert 'llm_wrapper' in AutoTraceStatus.__annotations__
    
    @pytest.mark.unit
    def test_tracing_config_type(self):
        """TracingConfig TypedDict is exported."""
        from swisper_studio_sdk import TracingConfig
        
        assert hasattr(TracingConfig, '__annotations__')
        assert 'redis_url' in TracingConfig.__annotations__
        assert 'project_id' in TracingConfig.__annotations__
    
    @pytest.mark.unit
    def test_observation_type_constants(self):
        """ObservationType constants are exported."""
        from swisper_studio_sdk import ObservationType
        
        assert ObservationType.AUTO == "AUTO"
        assert ObservationType.SPAN == "SPAN"
        assert ObservationType.GENERATION == "GENERATION"
        assert ObservationType.TOOL == "TOOL"
        assert ObservationType.AGENT == "AGENT"


class TestFunctionExports:
    """Verify function exports are callable."""
    
    @pytest.mark.unit
    def test_auto_trace_export(self):
        """auto_trace is exported and callable."""
        from swisper_studio_sdk import auto_trace
        assert callable(auto_trace)
    
    @pytest.mark.unit
    def test_safe_initialize_export(self):
        """safe_initialize is exported and callable."""
        from swisper_studio_sdk import safe_initialize
        assert callable(safe_initialize)
    
    @pytest.mark.unit
    def test_create_traced_graph_export(self):
        """create_traced_graph is exported and callable."""
        from swisper_studio_sdk import create_traced_graph
        assert callable(create_traced_graph)
    
    @pytest.mark.unit
    def test_traced_export(self):
        """traced decorator is exported and callable."""
        from swisper_studio_sdk import traced
        assert callable(traced)
    
    @pytest.mark.unit
    def test_langgraph_patching_exports(self):
        """LangGraph patching functions are exported."""
        from swisper_studio_sdk import (
            patch_langgraph,
            unpatch_langgraph,
            set_trace_name,
        )
        assert callable(patch_langgraph)
        assert callable(unpatch_langgraph)
        assert callable(set_trace_name)
    
    @pytest.mark.unit
    def test_wrapper_exports(self):
        """Wrapper functions are exported."""
        from swisper_studio_sdk import wrap_llm_adapter, wrap_tools
        assert callable(wrap_llm_adapter)
        assert callable(wrap_tools)
    
    @pytest.mark.unit
    def test_status_check_exports(self):
        """Status check functions are exported."""
        from swisper_studio_sdk import is_sdk_available, is_tracing_initialized
        assert callable(is_sdk_available)
        assert callable(is_tracing_initialized)
    
    @pytest.mark.unit
    def test_constant_exports(self):
        """Constants are exported."""
        from swisper_studio_sdk import DEFAULT_TIMEOUT
        assert isinstance(DEFAULT_TIMEOUT, (int, float))
        assert DEFAULT_TIMEOUT > 0


class TestDeprecation:
    """Verify deprecated functions emit warnings."""
    
    @pytest.mark.unit
    def test_initialize_tracing_deprecation_warning(self):
        """initialize_tracing emits DeprecationWarning."""
        from swisper_studio_sdk import initialize_tracing
        
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            
            # Call deprecated function - it may fail but should warn first
            try:
                initialize_tracing(api_key="test", api_url="http://test")
            except Exception:
                pass  # Expected - we just want to check the warning
            
            # Check warning was issued
            assert len(w) >= 1
            assert issubclass(w[0].category, DeprecationWarning)
            assert "deprecated" in str(w[0].message).lower()


class TestPyTypedMarker:
    """Verify py.typed marker exists."""
    
    @pytest.mark.unit
    def test_py_typed_marker_exists(self):
        """py.typed marker file exists for PEP 561 compliance."""
        import os
        import swisper_studio_sdk
        
        sdk_path = os.path.dirname(swisper_studio_sdk.__file__)
        py_typed_path = os.path.join(sdk_path, 'py.typed')
        
        assert os.path.exists(py_typed_path), "py.typed marker file missing"


class TestVersioning:
    """Verify version is defined."""
    
    @pytest.mark.unit
    def test_version_defined(self):
        """__version__ is defined and follows semver."""
        import swisper_studio_sdk
        
        assert hasattr(swisper_studio_sdk, '__version__')
        version = swisper_studio_sdk.__version__
        
        # Should be semver format (major.minor.patch)
        parts = version.split('.')
        assert len(parts) >= 2, f"Version {version} should be semver format"
        assert all(p.isdigit() for p in parts[:2]), f"Version {version} parts should be numeric"
