"""Index specification models for different deployment types."""

from __future__ import annotations

from typing import Any

from pinecone.models._base import BaseModel


class ServerlessReadCapacityStatus(BaseModel, kw_only=True):
    """Status information for serverless read capacity."""

    state: str
    current_shards: int | None = None
    current_replicas: int | None = None
    error_message: str | None = None


class ServerlessReadCapacityManual(BaseModel, kw_only=True):
    """Manual scaling configuration for serverless read capacity."""

    shards: int
    replicas: int


class ServerlessReadCapacityDedicated(BaseModel, kw_only=True):
    """Dedicated read capacity configuration."""

    node_type: str
    scaling: str
    manual: ServerlessReadCapacityManual | None = None


class ServerlessReadCapacity(BaseModel, kw_only=True):
    """Read capacity configuration for serverless indexes.

    Defines the read capacity mode and configuration for serverless indexes.
    Supports both on-demand and dedicated capacity modes.

    Attributes:
        mode: Capacity mode - "OnDemand" for automatic scaling or "Dedicated" for
            dedicated read nodes
        status: Current status of read capacity configuration
        dedicated: Dedicated capacity configuration (only present when mode is "Dedicated")

    Example:
        >>> info = pc.indexes.describe("my-index")
        >>> if info.spec.serverless:
        ...     rc = info.spec.serverless.read_capacity
        ...     print(f"Mode: {rc.mode}")
        ...     if rc.dedicated:
        ...         print(f"Node type: {rc.dedicated.node_type}")
    """

    mode: str
    status: ServerlessReadCapacityStatus
    dedicated: ServerlessReadCapacityDedicated | None = None


class ServerlessSpec(BaseModel, kw_only=True):
    """Serverless index specification.

    Defines the cloud provider, region, and read capacity configuration for
    a serverless index deployment.

    Attributes:
        cloud: Cloud provider - "aws", "gcp", or "azure"
        region: Cloud provider region (e.g., "us-east-1" for AWS, "us-east1" for GCP,
            "eastus" for Azure)
        read_capacity: Read capacity configuration (on-demand or dedicated)
        source_collection: Name of the collection used as source when creating this index
        schema: Metadata schema defining which fields are indexed and filterable

    Example:
        >>> info = pc.indexes.describe("my-index")
        >>> if info.spec.serverless:
        ...     print(f"Cloud: {info.spec.serverless.cloud}")
        ...     print(f"Region: {info.spec.serverless.region}")
        ...     print(f"Capacity mode: {info.spec.serverless.read_capacity.mode}")
        ...     if info.spec.serverless.source_collection:
        ...         print(f"Created from collection: {info.spec.serverless.source_collection}")
        ...     if info.spec.serverless.schema:
        ...         print(
        ...             f"Filterable fields: {list(info.spec.serverless.schema['fields'].keys())}"
        ...         )
    """

    cloud: str
    region: str
    read_capacity: ServerlessReadCapacity
    source_collection: str | None = None
    schema: dict[str, Any] | None = None


class PodSpec(BaseModel, kw_only=True):
    """Pod-based index specification.

    Defines the configuration for a pod-based index deployment, including
    the environment, pod type, and scaling parameters.

    Attributes:
        environment: Deployment environment (e.g., "us-east-1-aws")
        pod_type: Pod type specification (e.g., "p1.x1", "p2.x2")
        pods: Number of pods (defaults to 1 if not specified)
        replicas: Number of replicas per pod (defaults to 1 if not specified)
        shards: Number of shards (defaults to 1 if not specified)
        metadata_config: Optional metadata filtering configuration
        source_collection: Optional source collection for index creation

    Example:
        >>> info = pc.indexes.describe("my-index")
        >>> if info.spec.pod:
        ...     print(f"Environment: {info.spec.pod.environment}")
        ...     print(f"Pod type: {info.spec.pod.pod_type}")
        ...     print(f"Pods: {info.spec.pod.pods}")
    """

    environment: str
    pod_type: str
    pods: int | None = None
    replicas: int | None = None
    shards: int | None = None
    metadata_config: dict[str, Any] | None = None
    source_collection: str | None = None


class ByocSpec(BaseModel, kw_only=True):
    """BYOC (Bring Your Own Cloud) index specification.

    Defines the configuration for a Bring Your Own Cloud index deployment,
    which runs in your own cloud infrastructure with private endpoints.

    Attributes:
        environment: BYOC environment identifier (e.g., "aws-us-east-1-b921")
        read_capacity: Read capacity configuration (on-demand or dedicated)

    Example:
        >>> info = pc.indexes.describe("my-byoc-index")
        >>> if info.spec.byoc:
        ...     print(f"Environment: {info.spec.byoc.environment}")
        ...     print(f"Private host: {info.private_host}")
    """

    environment: str
    read_capacity: ServerlessReadCapacity


class IndexSpec(BaseModel, kw_only=True):
    """Index specification (serverless, pod-based, or BYOC).

    Represents the deployment configuration for an index. Exactly one of
    serverless, pod, or byoc will be set, depending on the index type.

    Attributes:
        serverless: Serverless index configuration (if this is a serverless index)
        pod: Pod-based index configuration (if this is a pod-based index)
        byoc: BYOC index configuration (if this is a BYOC index)

    Example:
        >>> info = pc.indexes.describe("my-index")
        >>> if info.spec.serverless:
        ...     print(f"Serverless index in {info.spec.serverless.cloud}")
        >>> elif info.spec.pod:
        ...     print(f"Pod index with type {info.spec.pod.pod_type}")
        >>> elif info.spec.byoc:
        ...     print(f"BYOC index in {info.spec.byoc.environment}")
    """

    serverless: ServerlessSpec | None = None
    pod: PodSpec | None = None
    byoc: ByocSpec | None = None
