"""Integration tests for Indexes namespace (2026-01.alpha API).

These tests make real API calls to Pinecone and require PINECONE_API_KEY.

Setup:
    export PINECONE_API_KEY="your-api-key"
    pytest tests/integration/test_indexes_integration.py -v

Note: These tests create and delete real indexes, which may incur API costs.
"""

import os
import time

import pytest

from pinecone import Pinecone
from pinecone.exceptions import NotFoundError


@pytest.fixture(scope="module")
def api_key():
    """Get API key from environment.

    Skips all tests if PINECONE_API_KEY not set.
    """
    key = os.getenv("PINECONE_API_KEY")
    if not key:
        pytest.skip("PINECONE_API_KEY not set")
    return key


@pytest.fixture(scope="module")
def client(api_key):
    """Create Pinecone client for testing.

    Module-scoped to reuse across tests.
    """
    return Pinecone(api_key=api_key)


def wait_for_index_ready(client, index_name, timeout=300, interval=5):
    """Wait for index to be ready.

    Args:
        client: Pinecone client
        index_name: Name of index to check
        timeout: Maximum seconds to wait (default 300 = 5 minutes)
        interval: Seconds between checks (default 5)

    Raises:
        TimeoutError: If index not ready within timeout
    """
    start = time.time()
    while time.time() - start < timeout:
        try:
            index = client.indexes.describe(index_name)
            if index.status.ready:
                return
        except Exception:
            pass  # Index may not exist yet
        time.sleep(interval)

    raise TimeoutError(f"Index {index_name} not ready after {timeout}s")


@pytest.mark.integration()
def test_create_and_delete_index_with_schema(client):
    """Test creating and deleting an index with the new schema-driven API.

    This test:
    1. Creates an index using the 2026-01.alpha API with schema
    2. Waits for the index to be ready
    3. Verifies the index was created correctly
    4. Deletes the index
    5. Verifies the index was deleted

    Note: deployment is optional and defaults to managed if not provided.
    """
    index_name = f"test-schema-{int(time.time())}"

    try:
        # Create index with schema-driven configuration
        # deployment is optional - omit to use default managed
        index = client.indexes.create(
            name=index_name,
            schema={
                "fields": {
                    "embedding": {
                        "type": "dense_vector",
                        "dimension": 384,
                        "metric": "cosine",
                    }
                }
            },
        )

        # Verify create response
        assert index.name == index_name
        assert index.schema is not None
        assert "embedding" in index.schema.fields
        assert index.schema.fields["embedding"].dimension == 384
        assert index.schema.fields["embedding"].metric == "cosine"

        # Wait for index to be ready
        print(f"Waiting for index {index_name} to be ready...")
        wait_for_index_ready(client, index_name)

        # Describe the index to verify it's fully created
        described = client.indexes.describe(index_name)
        assert described.name == index_name
        assert described.status.ready is True
        assert described.host is not None
        assert len(described.host) > 0

        # Verify schema matches what we created
        assert "embedding" in described.schema.fields
        assert described.schema.fields["embedding"].dimension == 384

    finally:
        # Always clean up - delete the index
        try:
            print(f"Cleaning up: deleting index {index_name}")
            client.indexes.delete(name=index_name)

            # Verify deletion
            time.sleep(2)  # Give API time to process deletion
            with pytest.raises(NotFoundError):
                client.indexes.describe(name=index_name)

        except Exception as e:
            print(f"Warning: Failed to delete index {index_name}: {e}")


# API Limitation: The 2026-01.alpha API does not support mixing vector fields
# with full-text searchable string fields in the same index. You can have either:
# - Vector search (dense_vector or sparse_vector) with filterable metadata, OR
# - Full-text search (full_text_searchable strings) without vector fields
# This is a current API limitation that may change in future versions.
#
@pytest.mark.integration()
@pytest.mark.skip(reason="API doesn't support vector + full-text search in same index")
def test_create_and_delete_fulltext_index(client):
    """Test creating an index with full-text search field.

    This test verifies:
    1. Full-text searchable string fields work
    2. Language parameter is properly set
    3. Index creation and deletion lifecycle
    """
    index_name = f"test-fulltext-{int(time.time())}"

    try:
        # Create index with full-text search field
        # deployment is optional - omit to use default managed
        index = client.indexes.create(
            name=index_name,
            schema={
                "fields": {
                    "text": {
                        "type": "string",
                        "full_text_searchable": True,
                        "language": "en",
                    },
                }
            },
        )

        # Verify field exists
        assert "text" in index.schema.fields
        assert index.schema.fields["text"].full_text_searchable is True
        assert index.schema.fields["text"].language == "en"

        # Wait for ready
        print(f"Waiting for index {index_name} to be ready...")
        wait_for_index_ready(client, index_name)

        # Verify it's ready
        described = client.indexes.describe(index_name)
        assert described.status.ready is True

    finally:
        # Clean up
        try:
            print(f"Cleaning up: deleting index {index_name}")
            client.indexes.delete(index_name)
        except Exception as e:
            print(f"Warning: Failed to delete index {index_name}: {e}")


@pytest.mark.integration()
def test_list_indexes(client):
    """Test listing indexes.

    This test verifies the list operation works and returns valid data.
    Note: This doesn't create/delete indexes to keep it fast and safe.
    """
    # List all indexes
    paginator = client.indexes.list()

    # Should be iterable
    assert hasattr(paginator, "__iter__")
    indexes = list(paginator)
    assert isinstance(indexes, list)

    # If indexes exist, verify structure
    for index in indexes:
        assert isinstance(index.name, str)
        assert len(index.name) > 0
        assert index.host is not None
        assert index.status is not None


@pytest.mark.integration()
@pytest.mark.skip(reason="Requires managed deployment with dedicated capacity configuration")
def test_create_managed_index_with_dedicated_capacity(client):
    """Test creating a managed index with dedicated read capacity.

    This test is skipped by default because:
    1. It requires a managed deployment configuration
    2. Dedicated capacity may require specific quota
    3. It's more expensive than on-demand capacity

    To run: pytest tests/integration/test_indexes_integration.py::test_create_managed_index_with_dedicated_capacity -v
    """
    index_name = f"test-managed-{int(time.time())}"

    try:
        # Create managed index with dedicated capacity
        index = client.indexes.create(
            name=index_name,
            schema={
                "fields": {
                    "embedding": {
                        "type": "dense_vector",
                        "dimension": 384,
                        "metric": "cosine",
                    }
                }
            },
            deployment={
                "deployment_type": "managed",
                "cloud": "aws",
                "region": "us-east-1",
            },
            read_capacity={
                "mode": "Dedicated",
                "dedicated": {
                    "node_type": "b1",
                    "scaling": "Manual",
                    "manual": {"shards": 1, "replicas": 1},
                },
            },
        )

        # Verify creation
        assert index.name == index_name
        assert index.read_capacity is not None

        # Wait for ready
        print(f"Waiting for managed index {index_name} to be ready...")
        wait_for_index_ready(client, index_name, timeout=600)  # Managed takes longer

        # Verify
        described = client.indexes.describe(index_name)
        assert described.status.ready is True

    finally:
        # Clean up
        try:
            print(f"Cleaning up: deleting index {index_name}")
            client.indexes.delete(index_name)
        except Exception as e:
            print(f"Warning: Failed to delete index {index_name}: {e}")
