"""Unit tests for AsyncIndexNamespace implementation."""

from __future__ import annotations

import pytest
import respx

from httpx import Response

from pinecone import AsyncPinecone
from pinecone.__interface__.indexes import AsyncIndexNamespaceProtocol
from pinecone._internal.http import AsyncHTTPClient
from pinecone.async_client.indexes_old import AsyncIndexNamespace
from pinecone.exceptions import APIError, NotFoundError


class TestAsyncIndexNamespaceProtocolCompliance:
    """Test that AsyncIndexNamespace satisfies AsyncIndexNamespaceProtocol."""

    def test_async_index_namespace_satisfies_protocol(self):
        """Verify AsyncIndexNamespace implements AsyncIndexNamespaceProtocol."""
        client = AsyncHTTPClient(api_key="test-key")
        instance = AsyncIndexNamespace(client)

        # Verify protocol satisfaction
        assert isinstance(instance, AsyncIndexNamespaceProtocol)

        # Verify all required methods exist
        assert hasattr(instance, "list")
        assert callable(instance.list)
        assert hasattr(instance, "create")
        assert callable(instance.create)
        assert hasattr(instance, "delete")
        assert callable(instance.delete)
        assert hasattr(instance, "describe")
        assert callable(instance.describe)


class TestAsyncIndexNamespaceList:
    """Test list() method."""

    @respx.mock
    @pytest.mark.asyncio()
    async def test_list_indexes_success(self):
        """Test successful list indexes operation."""
        # Mock API response
        mock_response = {
            "indexes": [
                {
                    "name": "test-index-1",
                    "metric": "cosine",
                    "vector_type": "dense",
                    "dimension": 1536,
                    "host": "test-index-1.pinecone.io",
                    "status": {"ready": True, "state": "Ready"},
                    "spec": {
                        "serverless": {
                            "cloud": "aws",
                            "region": "us-east-1",
                            "read_capacity": {
                                "mode": "OnDemand",
                                "status": {"state": "Ready"},
                            },
                        }
                    },
                },
                {
                    "name": "test-index-2",
                    "metric": "euclidean",
                    "vector_type": "dense",
                    "dimension": 768,
                    "host": "test-index-2.pinecone.io",
                    "deletion_protection": "enabled",
                    "tags": {"environment": "production"},
                    "status": {"ready": False, "state": "Initializing"},
                    "spec": {
                        "pod": {
                            "environment": "us-east1-gcp",
                            "pod_type": "p1.x1",
                            "pods": 1,
                            "replicas": 1,
                            "shards": 1,
                        }
                    },
                },
            ]
        }

        route = respx.get("https://api.pinecone.io/indexes").mock(
            return_value=Response(200, json=mock_response)
        )

        # Create client and call list
        async with AsyncPinecone(api_key="test-key") as pc:
            paginator = pc.indexes_old.list()
            indexes = []
            async for index in paginator:
                indexes.append(index)

        # Verify request
        assert route.called
        request = route.calls.last.request
        assert request.headers["X-Pinecone-Api-Version"] == "2025-10"
        assert request.headers["Api-Key"] == "test-key"

        # Verify response
        assert len(indexes) == 2

        # Verify first index
        index1 = indexes[0]
        assert index1.name == "test-index-1"
        assert index1.metric == "cosine"
        assert index1.vector_type == "dense"
        assert index1.dimension == 1536
        assert index1.host == "test-index-1.pinecone.io"
        assert index1.status_obj.ready is True
        assert index1.status_obj.state == "Ready"
        assert index1.status == "Ready"
        assert index1.spec.serverless is not None
        assert index1.spec.serverless.cloud == "aws"
        assert index1.spec.serverless.region == "us-east-1"
        assert index1.spec.serverless.read_capacity.mode == "OnDemand"
        assert index1.spec.pod is None

        # Verify second index
        index2 = indexes[1]
        assert index2.name == "test-index-2"
        assert index2.metric == "euclidean"
        assert index2.dimension == 768
        assert index2.deletion_protection == "enabled"
        assert index2.tags == {"environment": "production"}
        assert index2.status == "Initializing"
        assert index2.spec.pod is not None
        assert index2.spec.serverless is None

    @respx.mock
    @pytest.mark.asyncio()
    async def test_list_indexes_with_embed_field(self):
        """Test list indexes with embed configuration (from create_index_for_model)."""
        mock_response = {
            "indexes": [
                {
                    "name": "model-index",
                    "metric": "cosine",
                    "vector_type": "dense",
                    "dimension": 1024,
                    "host": "model-index.pinecone.io",
                    "status": {"ready": True, "state": "Ready"},
                    "embed": {
                        "model": "multilingual-e5-large",
                        "metric": "cosine",
                        "dimension": 1024,
                        "field_map": {"text": "content"},
                        "read_parameters": {"input_type": "query", "truncate": "NONE"},
                        "write_parameters": {"input_type": "passage"},
                    },
                    "spec": {
                        "serverless": {
                            "cloud": "aws",
                            "region": "us-east-1",
                            "read_capacity": {
                                "mode": "OnDemand",
                                "status": {"state": "Ready"},
                            },
                        }
                    },
                }
            ]
        }

        respx.get("https://api.pinecone.io/indexes").mock(
            return_value=Response(200, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            paginator = pc.indexes_old.list()
            indexes = []
            async for index in paginator:
                indexes.append(index)

        assert len(indexes) == 1
        index = indexes[0]
        assert index.name == "model-index"
        assert index.embed is not None
        assert index.embed["model"] == "multilingual-e5-large"
        assert index.embed["metric"] == "cosine"
        assert index.embed["dimension"] == 1024
        assert index.embed["field_map"] == {"text": "content"}
        assert index.embed["read_parameters"]["input_type"] == "query"
        assert index.embed["write_parameters"]["input_type"] == "passage"

    @respx.mock
    @pytest.mark.asyncio()
    async def test_list_indexes_with_schema_field(self):
        """Test list indexes with schema configuration (metadata filtering)."""
        mock_response = {
            "indexes": [
                {
                    "name": "schema-index",
                    "metric": "cosine",
                    "vector_type": "dense",
                    "dimension": 1536,
                    "host": "schema-index.pinecone.io",
                    "status": {"ready": True, "state": "Ready"},
                    "spec": {
                        "serverless": {
                            "cloud": "gcp",
                            "region": "us-east1",
                            "read_capacity": {
                                "mode": "OnDemand",
                                "status": {"state": "Ready"},
                            },
                            "schema": {
                                "fields": {
                                    "genre": {"filterable": True},
                                    "year": {"filterable": True},
                                    "title": {"filterable": True},
                                }
                            },
                        }
                    },
                }
            ]
        }

        respx.get("https://api.pinecone.io/indexes").mock(
            return_value=Response(200, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            paginator = pc.indexes_old.list()
            indexes = []
            async for index in paginator:
                indexes.append(index)

        assert len(indexes) == 1
        index = indexes[0]
        assert index.name == "schema-index"
        assert index.spec.serverless is not None
        assert index.spec.serverless.schema is not None
        schema_fields = index.spec.serverless.schema["fields"]
        assert "genre" in schema_fields
        assert "year" in schema_fields
        assert "title" in schema_fields
        assert schema_fields["genre"]["filterable"] is True

    @respx.mock
    @pytest.mark.asyncio()
    async def test_list_indexes_with_source_collection_field(self):
        """Test list indexes with source_collection field."""
        mock_response = {
            "indexes": [
                {
                    "name": "from-collection",
                    "metric": "cosine",
                    "vector_type": "dense",
                    "dimension": 768,
                    "host": "from-collection.pinecone.io",
                    "status": {"ready": True, "state": "Ready"},
                    "spec": {
                        "serverless": {
                            "cloud": "aws",
                            "region": "us-west-2",
                            "read_capacity": {
                                "mode": "OnDemand",
                                "status": {"state": "Ready"},
                            },
                            "source_collection": "my-backup-collection",
                        }
                    },
                }
            ]
        }

        respx.get("https://api.pinecone.io/indexes").mock(
            return_value=Response(200, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            paginator = pc.indexes_old.list()
            indexes = []
            async for index in paginator:
                indexes.append(index)

        assert len(indexes) == 1
        index = indexes[0]
        assert index.name == "from-collection"
        assert index.spec.serverless is not None
        assert index.spec.serverless.source_collection == "my-backup-collection"


class TestAsyncIndexNamespaceCreate:
    """Test create() method."""

    @respx.mock
    @pytest.mark.asyncio()
    async def test_create_serverless_index_success(self):
        """Test successful serverless index creation."""
        mock_response = {
            "name": "test-serverless-index",
            "metric": "cosine",
            "vector_type": "dense",
            "dimension": 1536,
            "host": "test-serverless-index.pinecone.io",
            "status": {"ready": False, "state": "Initializing"},
            "deletion_protection": "disabled",
            "spec": {
                "serverless": {
                    "cloud": "aws",
                    "region": "us-east-1",
                    "read_capacity": {
                        "mode": "OnDemand",
                        "status": {"state": "Ready"},
                    },
                }
            },
        }

        route = respx.post("https://api.pinecone.io/indexes").mock(
            return_value=Response(201, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            result = await pc.indexes_old.create(
                name="test-serverless-index",
                dimension=1536,
                metric="cosine",
                spec={"cloud": "aws", "region": "us-east-1"},
            )

        # Verify request
        assert route.called
        request = route.calls.last.request
        assert request.headers["X-Pinecone-Api-Version"] == "2025-10"
        assert request.headers["Api-Key"] == "test-key"
        assert request.headers["Content-Type"] == "application/json"

        # Verify request body
        import orjson

        body = orjson.loads(request.content)
        assert body["name"] == "test-serverless-index"
        assert body["dimension"] == 1536
        assert body["metric"] == "cosine"
        assert body["vector_type"] == "dense"
        assert body["deletion_protection"] == "disabled"
        assert body["spec"]["serverless"]["cloud"] == "aws"
        assert body["spec"]["serverless"]["region"] == "us-east-1"

        # Verify response
        assert result.name == "test-serverless-index"
        assert result.host == "test-serverless-index.pinecone.io"
        assert result.status == "Initializing"

    @respx.mock
    @pytest.mark.asyncio()
    async def test_create_sparse_index(self):
        """Test sparse index creation (no dimension)."""
        mock_response = {
            "name": "sparse-index",
            "metric": "dotproduct",
            "vector_type": "sparse",
            "host": "sparse-index.pinecone.io",
            "status": {"ready": False, "state": "Initializing"},
            "deletion_protection": "disabled",
            "spec": {
                "serverless": {
                    "cloud": "gcp",
                    "region": "us-east1",
                    "read_capacity": {
                        "mode": "OnDemand",
                        "status": {"state": "Ready"},
                    },
                }
            },
        }

        route = respx.post("https://api.pinecone.io/indexes").mock(
            return_value=Response(201, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            result = await pc.indexes_old.create(
                name="sparse-index",
                metric="dotproduct",
                vector_type="sparse",
                spec={"cloud": "gcp", "region": "us-east1"},
            )

        # Verify request
        assert route.called
        request = route.calls.last.request
        import orjson

        body = orjson.loads(request.content)
        assert body["vector_type"] == "sparse"
        assert "dimension" not in body

        # Verify response
        assert result.name == "sparse-index"
        assert result.vector_type == "sparse"

    @respx.mock
    @pytest.mark.asyncio()
    async def test_create_pod_index(self):
        """Test pod-based index creation."""
        mock_response = {
            "name": "pod-index",
            "metric": "cosine",
            "vector_type": "dense",
            "dimension": 1536,
            "host": "pod-index.pinecone.io",
            "status": {"ready": False, "state": "Initializing"},
            "deletion_protection": "disabled",
            "spec": {
                "pod": {
                    "environment": "us-east1-gcp",
                    "pod_type": "p1.x1",
                    "pods": 1,
                    "replicas": 1,
                    "shards": 1,
                }
            },
        }

        route = respx.post("https://api.pinecone.io/indexes").mock(
            return_value=Response(201, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            result = await pc.indexes_old.create(
                name="pod-index",
                dimension=1536,
                metric="cosine",
                spec={
                    "environment": "us-east1-gcp",
                    "pod_type": "p1.x1",
                    "pods": 1,
                    "replicas": 1,
                    "shards": 1,
                },
            )

        # Verify request
        assert route.called
        request = route.calls.last.request
        import orjson

        body = orjson.loads(request.content)
        assert body["spec"]["pod"]["environment"] == "us-east1-gcp"
        assert body["spec"]["pod"]["pod_type"] == "p1.x1"
        assert body["spec"]["pod"]["pods"] == 1

        # Verify response
        assert result.name == "pod-index"
        assert result.spec.pod is not None
        assert result.spec.pod.environment == "us-east1-gcp"
        assert result.spec.pod.pod_type == "p1.x1"

    @respx.mock
    @pytest.mark.asyncio()
    async def test_create_pod_index_minimal_spec(self):
        """Test pod-based index creation with minimal spec (no pods/replicas/shards)."""
        mock_response = {
            "name": "minimal-pod-index",
            "metric": "cosine",
            "vector_type": "dense",
            "dimension": 1536,
            "host": "minimal-pod-index.pinecone.io",
            "status": {"ready": False, "state": "Initializing"},
            "deletion_protection": "disabled",
            "spec": {
                "pod": {
                    "environment": "us-west1-gcp",
                    "pod_type": "p1.x1",
                    "pods": 1,
                    "replicas": 1,
                    "shards": 1,
                }
            },
        }

        route = respx.post("https://api.pinecone.io/indexes").mock(
            return_value=Response(201, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            # Create with only required fields (environment and pod_type)
            result = await pc.indexes_old.create(
                name="minimal-pod-index",
                dimension=1536,
                metric="cosine",
                spec={
                    "environment": "us-west1-gcp",
                    "pod_type": "p1.x1",
                },
            )

        # Verify request - pods/replicas/shards should not be in request if not specified
        assert route.called
        request = route.calls.last.request
        import orjson

        body = orjson.loads(request.content)
        assert body["spec"]["pod"]["environment"] == "us-west1-gcp"
        assert body["spec"]["pod"]["pod_type"] == "p1.x1"
        # These fields should either not be present or be None in the request
        # (API will use defaults)

        # Verify response - API returns default values
        assert result.name == "minimal-pod-index"
        assert result.spec.pod is not None
        assert result.spec.pod.environment == "us-west1-gcp"
        assert result.spec.pod.pod_type == "p1.x1"
        assert result.spec.pod.pods == 1  # API default
        assert result.spec.pod.replicas == 1  # API default
        assert result.spec.pod.shards == 1  # API default

    @respx.mock
    @pytest.mark.asyncio()
    async def test_create_byoc_index(self):
        """Test BYOC index creation."""
        mock_response = {
            "name": "byoc-index",
            "metric": "cosine",
            "vector_type": "dense",
            "dimension": 1536,
            "host": "byoc-index.svc.aped-4627-b74a.pinecone.io",
            "private_host": "byoc-index.svc.private.aped-4627-b74a.pinecone.io",
            "status": {"ready": True, "state": "Ready"},
            "deletion_protection": "disabled",
            "spec": {
                "byoc": {
                    "environment": "aws-us-east-1-b921",
                    "read_capacity": {
                        "mode": "OnDemand",
                        "status": {"state": "Ready"},
                    },
                }
            },
        }

        route = respx.post("https://api.pinecone.io/indexes").mock(
            return_value=Response(201, json=mock_response)
        )

        async with AsyncPinecone(api_key="test-key") as pc:
            result = await pc.indexes_old.create(
                name="byoc-index",
                dimension=1536,
                metric="cosine",
                spec={"environment": "aws-us-east-1-b921"},
            )

        # Verify request
        assert route.called
        request = route.calls.last.request
        import orjson

        body = orjson.loads(request.content)
        assert body["spec"]["byoc"]["environment"] == "aws-us-east-1-b921"

        # Verify response
        assert result.name == "byoc-index"
        assert result.spec.byoc is not None
        assert result.spec.byoc.environment == "aws-us-east-1-b921"
        assert result.host == "byoc-index.svc.aped-4627-b74a.pinecone.io"
        assert result.private_host == "byoc-index.svc.private.aped-4627-b74a.pinecone.io"

    @pytest.mark.asyncio()
    async def test_create_validates_empty_name(self):
        """Test create validates empty name."""
        async with AsyncPinecone(api_key="test-key") as pc:
            with pytest.raises(ValueError, match="name must be a non-empty string"):
                await pc.indexes_old.create(
                    name="",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_dimension_range(self):
        """Test create validates dimension is in valid range."""
        async with AsyncPinecone(api_key="test-key") as pc:
            with pytest.raises(ValueError, match="dimension must be between 1 and 20000"):
                await pc.indexes_old.create(
                    name="test-index",
                    dimension=0,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_dimension_required_for_dense(self):
        """Test create validates dimension is required for dense indexes."""
        async with AsyncPinecone(api_key="test-key") as pc:
            with pytest.raises(ValueError, match="dimension is required for dense indexes"):
                await pc.indexes_old.create(
                    name="test-index",
                    vector_type="dense",
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_name_length(self):
        """Test create validates index name length."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Name too long (46 characters)
            long_name = "a" * 46
            with pytest.raises(ValueError, match="exceeds 45 character limit"):
                await pc.indexes_old.create(
                    name=long_name,
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_name_format(self):
        """Test create validates index name format."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Name with uppercase letters
            with pytest.raises(ValueError, match="contains invalid characters"):
                await pc.indexes_old.create(
                    name="Test-Index",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

            # Name with underscores
            with pytest.raises(ValueError, match="contains invalid characters"):
                await pc.indexes_old.create(
                    name="test_index",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

            # Name with special characters
            with pytest.raises(ValueError, match="contains invalid characters"):
                await pc.indexes_old.create(
                    name="test@index",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_tag_key_length(self):
        """Test create validates tag key length."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Tag key too long (81 characters)
            long_key = "k" * 81
            with pytest.raises(ValueError, match=r"Tag key .* exceeds 80 character limit"):
                await pc.indexes_old.create(
                    name="test-index",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                    tags={long_key: "value"},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_tag_value_length(self):
        """Test create validates tag value length."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Tag value too long (121 characters)
            long_value = "v" * 121
            with pytest.raises(ValueError, match=r"Tag value .* exceeds 120 character limit"):
                await pc.indexes_old.create(
                    name="test-index",
                    dimension=1536,
                    spec={"cloud": "aws", "region": "us-east-1"},
                    tags={"key": long_value},
                )

    @pytest.mark.asyncio()
    async def test_create_validates_incomplete_pod_spec_with_metadata_config(self):
        """Test create detects incomplete pod spec with metadata_config but missing pod_type."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Has environment and metadata_config but missing pod_type
            with pytest.raises(
                ValueError, match=r"Incomplete pod spec detected.*missing required 'pod_type'"
            ):
                await pc.indexes_old.create(
                    name="test-index",
                    dimension=1536,
                    spec={
                        "environment": "us-west1-gcp",
                        "metadata_config": {"indexed": ["genre", "year"]},
                    },
                )

    @pytest.mark.asyncio()
    async def test_create_validates_incomplete_pod_spec_with_source_collection(self):
        """Test create detects incomplete pod spec with source_collection but missing pod_type."""
        async with AsyncPinecone(api_key="test-key") as pc:
            # Has environment and source_collection but missing pod_type
            with pytest.raises(
                ValueError, match=r"Incomplete pod spec detected.*missing required 'pod_type'"
            ):
                await pc.indexes_old.create(
                    name="test-index",
                    dimension=1536,
                    spec={
                        "environment": "us-west1-gcp",
                        "source_collection": "my-collection",
                    },
                )


class TestAsyncIndexNamespaceConcurrency:
    """Test concurrent operations."""

    @respx.mock
    @pytest.mark.asyncio()
    async def test_concurrent_create_operations(self):
        """Test creating multiple indexes concurrently."""
        import asyncio

        def create_response(request):
            """Generate response based on request body."""
            import orjson

            body = orjson.loads(request.content)
            index_name = body["name"]
            return Response(
                201,
                json={
                    "name": index_name,
                    "metric": "cosine",
                    "vector_type": "dense",
                    "dimension": 128,
                    "host": f"{index_name}.pinecone.io",
                    "status": {"ready": False, "state": "Initializing"},
                    "deletion_protection": "disabled",
                    "spec": {
                        "serverless": {
                            "cloud": "aws",
                            "region": "us-east-1",
                            "read_capacity": {
                                "mode": "OnDemand",
                                "status": {"state": "Ready"},
                            },
                        }
                    },
                },
            )

        # Mock with callback to return different responses
        respx.post("https://api.pinecone.io/indexes").mock(side_effect=create_response)

        async with AsyncPinecone(api_key="test-key") as pc:
            # Create 3 indexes concurrently
            tasks = [
                pc.indexes_old.create(
                    name=f"test-index-{i}",
                    dimension=128,
                    spec={"cloud": "aws", "region": "us-east-1"},
                )
                for i in range(1, 4)
            ]
            results = await asyncio.gather(*tasks)

        # Verify all succeeded
        assert len(results) == 3
        result_names = {result.name for result in results}
        assert result_names == {"test-index-1", "test-index-2", "test-index-3"}
        for result in results:
            assert result.status == "Initializing"


class TestAsyncIndexNamespaceDescribe:
    """Test describe() method."""

    @pytest.mark.asyncio()
    @respx.mock
    async def test_describe_success(self):
        """Test successful index describe."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        mock_response = {
            "name": "test-index",
            "dimension": 1536,
            "metric": "cosine",
            "vector_type": "dense",
            "host": "test-index-abc123.svc.pinecone.io",
            "status": {"ready": True, "state": "Ready"},
            "spec": {
                "serverless": {
                    "cloud": "aws",
                    "region": "us-east-1",
                    "read_capacity": {
                        "mode": "OnDemand",
                        "status": {"state": "Ready"},
                    },
                }
            },
        }

        respx.get("https://api.pinecone.io/indexes/test-index").mock(
            return_value=Response(200, json=mock_response)
        )

        result = await namespace.describe("test-index")

        assert result.name == "test-index"
        assert result.config.dimension == 1536
        assert result.config.metric == "cosine"
        assert result.host == "test-index-abc123.svc.pinecone.io"
        assert result.status == "Ready"

    @pytest.mark.asyncio()
    @respx.mock
    async def test_describe_not_found(self):
        """Test describe() with non-existent index."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        respx.get("https://api.pinecone.io/indexes/nonexistent").mock(
            return_value=Response(
                404,
                json={
                    "error": {"code": "NOT_FOUND", "message": "Index not found"},
                    "status": 404,
                },
            )
        )

        with pytest.raises(NotFoundError, match="Index not found"):
            await namespace.describe("nonexistent")

    @pytest.mark.asyncio()
    async def test_describe_empty_name(self):
        """Test describe() with empty name."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        with pytest.raises(ValueError, match="name must be a non-empty string"):
            await namespace.describe("")


class TestAsyncIndexNamespaceDelete:
    """Test delete() method."""

    @pytest.mark.asyncio()
    @respx.mock
    async def test_delete_success(self):
        """Test successful index deletion."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        respx.delete("https://api.pinecone.io/indexes/test-index").mock(return_value=Response(202))

        # Should not raise
        await namespace.delete("test-index")

    @pytest.mark.asyncio()
    @respx.mock
    async def test_delete_with_timeout(self):
        """Test delete() with custom timeout."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        mock = respx.delete("https://api.pinecone.io/indexes/test-index").mock(
            return_value=Response(202)
        )

        await namespace.delete("test-index", timeout=60)

        # Verify timeout was passed
        assert mock.called

    @pytest.mark.asyncio()
    @respx.mock
    async def test_delete_not_found(self):
        """Test delete() with non-existent index."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        respx.delete("https://api.pinecone.io/indexes/nonexistent").mock(
            return_value=Response(
                404,
                json={
                    "error": {"code": "NOT_FOUND", "message": "Index not found"},
                    "status": 404,
                },
            )
        )

        with pytest.raises(NotFoundError, match="Index not found"):
            await namespace.delete("nonexistent")

    @pytest.mark.asyncio()
    @respx.mock
    async def test_delete_with_pending_collection(self):
        """Test delete() with pending collection."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        respx.delete("https://api.pinecone.io/indexes/test-index").mock(
            return_value=Response(
                412,
                json={
                    "error": {
                        "code": "FAILED_PRECONDITION",
                        "message": "There is a pending collection from this index",
                    },
                    "status": 412,
                },
            )
        )

        with pytest.raises(APIError, match="There is a pending collection"):
            await namespace.delete("test-index")

    @pytest.mark.asyncio()
    async def test_delete_empty_name(self):
        """Test delete() with empty name."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        with pytest.raises(ValueError, match="name must be a non-empty string"):
            await namespace.delete("")

    @pytest.mark.asyncio()
    async def test_delete_invalid_timeout_negative(self):
        """Test delete() with negative timeout."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        with pytest.raises(ValueError, match="timeout must be a positive integer"):
            await namespace.delete("my-index", timeout=-1)

    @pytest.mark.asyncio()
    async def test_delete_invalid_timeout_zero(self):
        """Test delete() with zero timeout."""
        client = AsyncHTTPClient(api_key="test-key")
        namespace = AsyncIndexNamespace(client)

        with pytest.raises(ValueError, match="timeout must be a positive integer"):
            await namespace.delete("my-index", timeout=0)
