"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from .endpointstatus import EndpointStatus
from .parameter import Parameter
from .percentilestats import PercentileStats, PercentileStatsTypedDict
from .providername import ProviderName
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict


class PricingTypedDict(TypedDict):
    prompt: str
    r"""A value in string format that is a large number"""
    completion: str
    r"""A value in string format that is a large number"""
    request: NotRequired[str]
    r"""A value in string format that is a large number"""
    image: NotRequired[str]
    r"""A value in string format that is a large number"""
    image_token: NotRequired[str]
    r"""A value in string format that is a large number"""
    image_output: NotRequired[str]
    r"""A value in string format that is a large number"""
    audio: NotRequired[str]
    r"""A value in string format that is a large number"""
    input_audio_cache: NotRequired[str]
    r"""A value in string format that is a large number"""
    web_search: NotRequired[str]
    r"""A value in string format that is a large number"""
    internal_reasoning: NotRequired[str]
    r"""A value in string format that is a large number"""
    input_cache_read: NotRequired[str]
    r"""A value in string format that is a large number"""
    input_cache_write: NotRequired[str]
    r"""A value in string format that is a large number"""
    discount: NotRequired[float]


class Pricing(BaseModel):
    prompt: str
    r"""A value in string format that is a large number"""

    completion: str
    r"""A value in string format that is a large number"""

    request: Optional[str] = None
    r"""A value in string format that is a large number"""

    image: Optional[str] = None
    r"""A value in string format that is a large number"""

    image_token: Optional[str] = None
    r"""A value in string format that is a large number"""

    image_output: Optional[str] = None
    r"""A value in string format that is a large number"""

    audio: Optional[str] = None
    r"""A value in string format that is a large number"""

    input_audio_cache: Optional[str] = None
    r"""A value in string format that is a large number"""

    web_search: Optional[str] = None
    r"""A value in string format that is a large number"""

    internal_reasoning: Optional[str] = None
    r"""A value in string format that is a large number"""

    input_cache_read: Optional[str] = None
    r"""A value in string format that is a large number"""

    input_cache_write: Optional[str] = None
    r"""A value in string format that is a large number"""

    discount: Optional[float] = None


PublicEndpointQuantization = Union[
    Literal[
        "int4",
        "int8",
        "fp4",
        "fp6",
        "fp8",
        "fp16",
        "bf16",
        "fp32",
        "unknown",
    ],
    UnrecognizedStr,
]


class PublicEndpointTypedDict(TypedDict):
    r"""Information about a specific model endpoint"""

    name: str
    model_name: str
    context_length: float
    pricing: PricingTypedDict
    provider_name: ProviderName
    tag: str
    quantization: Nullable[PublicEndpointQuantization]
    max_completion_tokens: Nullable[float]
    max_prompt_tokens: Nullable[float]
    supported_parameters: List[Parameter]
    uptime_last_30m: Nullable[float]
    supports_implicit_caching: bool
    latency_last_30m: Nullable[PercentileStatsTypedDict]
    r"""Latency percentiles in milliseconds over the last 30 minutes. Latency measures time to first token. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests."""
    throughput_last_30m: Nullable[PercentileStatsTypedDict]
    status: NotRequired[EndpointStatus]


class PublicEndpoint(BaseModel):
    r"""Information about a specific model endpoint"""

    name: str

    model_name: str

    context_length: float

    pricing: Pricing

    provider_name: Annotated[ProviderName, PlainValidator(validate_open_enum(False))]

    tag: str

    quantization: Annotated[
        Nullable[PublicEndpointQuantization], PlainValidator(validate_open_enum(False))
    ]

    max_completion_tokens: Nullable[float]

    max_prompt_tokens: Nullable[float]

    supported_parameters: List[
        Annotated[Parameter, PlainValidator(validate_open_enum(False))]
    ]

    uptime_last_30m: Nullable[float]

    supports_implicit_caching: bool

    latency_last_30m: Nullable[PercentileStats]
    r"""Latency percentiles in milliseconds over the last 30 minutes. Latency measures time to first token. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests."""

    throughput_last_30m: Nullable[PercentileStats]

    status: Annotated[
        Optional[EndpointStatus], PlainValidator(validate_open_enum(True))
    ] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["status"]
        nullable_fields = [
            "quantization",
            "max_completion_tokens",
            "max_prompt_tokens",
            "uptime_last_30m",
            "latency_last_30m",
            "throughput_last_30m",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
