"""
Test PEP 561 compliance for type distribution.

This module verifies that the augint_library package correctly provides
type information to users through the py.typed marker file.
"""

import importlib.util
import subprocess
import tempfile
from pathlib import Path

import pytest

from augint_library import __file__ as library_init_file


class TestPEP561Compliance:
    """Test suite for PEP 561 type distribution compliance."""

    def test_py_typed_file_exists(self) -> None:
        """Test that py.typed marker file exists in the package."""
        library_path = Path(library_init_file).parent
        py_typed_path = library_path / "py.typed"

        assert py_typed_path.exists(), "py.typed marker file must exist for PEP 561 compliance"

    def test_py_typed_file_is_empty(self) -> None:
        """Test that py.typed file is empty as per PEP 561 specification."""
        library_path = Path(library_init_file).parent
        py_typed_path = library_path / "py.typed"

        # File should exist and be empty (0 bytes)
        assert py_typed_path.stat().st_size == 0, "py.typed file should be empty"

    def test_mypy_can_find_types(self) -> None:
        """Test that mypy can successfully find and use type information."""
        test_code = """
import augint_library
from augint_library.core import print_hi, fetch_data

# Test that mypy recognizes the function types
print_hi("test")
data = fetch_data("/api/test", timeout=5.0)
reveal_type(data)
"""

        with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
            f.write(test_code)
            temp_file = Path(f.name)

        try:
            # Run mypy on the test code
            result = subprocess.run(
                ["python", "-m", "mypy", "--no-error-summary", str(temp_file)],
                check=False,
                capture_output=True,
                text=True,
                timeout=30,
            )

            # mypy should run without critical errors
            # Note: reveal_type will generate output, but that's expected
            assert result.returncode in [0, 1], (
                f"mypy failed with unexpected error: {result.stderr}"
            )

            # Check that mypy found the type information
            # Should show dict type for the return value of fetch_data
            assert "builtins.dict" in result.stdout or "Dict" in result.stdout, (
                "mypy should be able to resolve fetch_data return type"
            )

        except subprocess.TimeoutExpired:
            pytest.fail("mypy timed out - possible configuration issue")
        except FileNotFoundError:
            pytest.skip("mypy not available in test environment")
        finally:
            temp_file.unlink(missing_ok=True)

    def test_package_is_typed_according_to_pep561(self) -> None:
        """Test that the package structure follows PEP 561 guidelines."""
        library_path = Path(library_init_file).parent

        # Check that we have an __init__.py (required for packages)
        init_file = library_path / "__init__.py"
        assert init_file.exists(), "Package must have __init__.py"

        # Check that py.typed is at the package root level
        py_typed_path = library_path / "py.typed"
        assert py_typed_path.exists(), "py.typed must be at package root"

        # Verify the py.typed file is in the same directory as __init__.py
        assert py_typed_path.parent == init_file.parent, (
            "py.typed must be in the same directory as __init__.py"
        )

    def test_type_stub_quality(self) -> None:
        """Test that the library exports have proper type annotations."""
        # Import the library and check that main exports are properly typed
        from augint_library.core import fetch_data, print_hi
        from augint_library.protocols import CacheProvider, DataProcessor

        # These should all have proper type information available
        assert hasattr(print_hi, "__annotations__"), "print_hi should have type annotations"
        assert hasattr(fetch_data, "__annotations__"), "fetch_data should have type annotations"

        # Check that protocols have proper typing
        assert hasattr(DataProcessor, "process"), "DataProcessor should have process method"
        assert hasattr(DataProcessor, "batch_process"), (
            "DataProcessor should have batch_process method"
        )
        assert hasattr(CacheProvider, "get"), "CacheProvider should have get method"
        assert hasattr(CacheProvider, "set"), "CacheProvider should have set method"

    def test_installed_package_includes_py_typed(self) -> None:
        """Test that py.typed is included when package is installed."""
        # Check if we can find the py.typed file via the module spec
        spec = importlib.util.find_spec("augint_library")
        assert spec is not None, "Could not find augint_library module spec"

        if spec.origin is not None:
            # For regular packages, check that py.typed exists alongside the module
            module_path = Path(spec.origin).parent
            py_typed_path = module_path / "py.typed"

            assert py_typed_path.exists(), (
                f"py.typed not found in installed package at {module_path}"
            )
