"""Unit tests for AsyncIndex data plane client."""

import os

import pytest

from pinecone.async_index import AsyncIndex


pytestmark = pytest.mark.unit


class TestAsyncIndexConstruction:
    """Tests for AsyncIndex initialization and configuration."""

    def test_construction_with_host_and_api_key(self):
        index = AsyncIndex(host="my-index-abc123.svc.pinecone.io", api_key="test-key")

        assert index._host == "my-index-abc123.svc.pinecone.io"
        assert index._api_key == "test-key"

    def test_requires_api_key(self):
        original_api_key = os.environ.get("PINECONE_API_KEY")

        try:
            if "PINECONE_API_KEY" in os.environ:
                del os.environ["PINECONE_API_KEY"]

            with pytest.raises(ValueError, match="api_key is required"):
                AsyncIndex(host="my-index.svc.pinecone.io")
        finally:
            if original_api_key is not None:
                os.environ["PINECONE_API_KEY"] = original_api_key

    def test_uses_env_var_api_key(self):
        original_api_key = os.environ.get("PINECONE_API_KEY")

        try:
            os.environ["PINECONE_API_KEY"] = "env-test-key"
            index = AsyncIndex(host="my-index.svc.pinecone.io")
            assert index._api_key == "env-test-key"
        finally:
            if original_api_key is not None:
                os.environ["PINECONE_API_KEY"] = original_api_key
            elif "PINECONE_API_KEY" in os.environ:
                del os.environ["PINECONE_API_KEY"]

    def test_parameter_overrides_env_var(self):
        original_api_key = os.environ.get("PINECONE_API_KEY")

        try:
            os.environ["PINECONE_API_KEY"] = "env-key"
            index = AsyncIndex(host="my-index.svc.pinecone.io", api_key="param-key")
            assert index._api_key == "param-key"
        finally:
            if original_api_key is not None:
                os.environ["PINECONE_API_KEY"] = original_api_key
            elif "PINECONE_API_KEY" in os.environ:
                del os.environ["PINECONE_API_KEY"]

    def test_default_timeout(self):
        index = AsyncIndex(host="my-index.svc.pinecone.io", api_key="test-key")
        assert index._timeout == 30

    def test_custom_timeout(self):
        index = AsyncIndex(host="my-index.svc.pinecone.io", api_key="test-key", timeout=60)
        assert index._timeout == 60

    def test_additional_headers_stored(self):
        headers = {"X-Custom": "value"}
        index = AsyncIndex(
            host="my-index.svc.pinecone.io",
            api_key="test-key",
            additional_headers=headers,
        )
        assert index._additional_headers == headers

    def test_keyword_only_args(self):
        with pytest.raises(TypeError):
            AsyncIndex("my-index.svc.pinecone.io", "test-key")  # type: ignore[misc]


class TestAsyncIndexLifecycle:
    """Tests for AsyncIndex async context manager and close()."""

    @pytest.mark.asyncio()
    async def test_async_context_manager(self):
        async with AsyncIndex(host="my-index.svc.pinecone.io", api_key="test-key") as index:
            assert index is not None
            assert isinstance(index, AsyncIndex)

    @pytest.mark.asyncio()
    async def test_close(self):
        index = AsyncIndex(host="my-index.svc.pinecone.io", api_key="test-key")
        await index.close()  # Should not raise

    def test_repr(self):
        index = AsyncIndex(host="my-index-abc123.svc.pinecone.io", api_key="test-key")
        assert repr(index) == "AsyncIndex(host='my-index-abc123.svc.pinecone.io')"

    def test_multiple_instances(self):
        idx1 = AsyncIndex(host="host-a.svc.pinecone.io", api_key="key1")
        idx2 = AsyncIndex(host="host-b.svc.pinecone.io", api_key="key2")

        assert idx1 is not idx2
        assert idx1._host != idx2._host


class TestAsyncIndexExport:
    """Tests for AsyncIndex availability from pinecone package."""

    def test_importable_from_package(self):
        from pinecone import AsyncIndex as PineconeAsyncIndex

        assert PineconeAsyncIndex is AsyncIndex
