"""Describe method for indexes namespace."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, cast

import orjson

from pinecone._internal.constants import INDEXES_API_VERSION
from pinecone._internal.logging import get_logger
from pinecone._internal.validation import require_non_empty
from pinecone.exceptions import APIError


if TYPE_CHECKING:
    from pinecone.__interface__.indexes import IndexInfoProtocol
else:
    IndexInfoProtocol = object


logger = get_logger(__name__)


def describe(self: Any, name: str) -> IndexInfoProtocol:
    """Describe a specific index.

    Args:
        name: Index name (string) to describe.

    Returns:
        IndexInfo with metadata and configuration.

    Raises:
        ValueError: If name is empty
        NotFoundError: If index does not exist
        APIError: If the API returns an error response
        APIConnectionError: If the request fails to connect
        TimeoutError: If the request times out

    Example:
        >>> info = pc.indexes.describe("my-index")
        >>> print(f"Dimension: {info.config.dimension}")
        >>> print(f"Metric: {info.config.metric}")
        >>> print(f"Host: {info.host}")
        >>> print(f"Status: {info.status}")

    Example checking status:
        >>> info = pc.indexes.describe("my-index")
        >>> if info.status.ready:
        ...     print("Index is ready for queries")
        ... else:
        ...     print(f"Index state: {info.status.state}")

    Example waiting for index to be ready:
        >>> import time
        >>> # Poll until index is ready
        >>> while True:
        ...     info = pc.indexes.describe("my-index")
        ...     if info.status.ready:
        ...         print("Index is ready!")
        ...         break
        ...     print(f"Index state: {info.status.state}")
        ...     time.sleep(5)
    """
    require_non_empty("name", name)

    logger.info("Describing index", index_name=name)

    try:
        response = self._http.get(
            f"{self._base_url}/indexes/{name}",
            headers={
                "X-Pinecone-Api-Version": INDEXES_API_VERSION,
            },
        )

        data = orjson.loads(response.content)
        result = self._adapter.to_index_model(data)

        logger.debug("Successfully described index", index_name=name)

        # Cast to IndexInfoProtocol for type checker
        return cast("IndexInfoProtocol", result)

    except (ValueError, KeyError, TypeError) as e:
        logger.exception("Failed to parse index response", index_name=name)
        raise APIError(
            status_code=500,
            message=f"Failed to parse response for index '{name}'. "
            f"The API may have returned an unexpected format. "
            f"Original error: {e}",
        ) from e
    except Exception:
        logger.exception("Failed to describe index", index_name=name)
        raise
