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

from __future__ import annotations
from datetime import datetime
from enum import Enum
from outpost_sdk.types import BaseModel, UNSET_SENTINEL
from outpost_sdk.utils import FieldMetadata, QueryParamMetadata
import pydantic
from pydantic import model_serializer
from typing import List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


class GetAttemptMetricsMeasuresEnum2(str, Enum):
    COUNT = "count"
    SUCCESSFUL_COUNT = "successful_count"
    FAILED_COUNT = "failed_count"
    ERROR_RATE = "error_rate"
    FIRST_ATTEMPT_COUNT = "first_attempt_count"
    RETRY_COUNT = "retry_count"
    MANUAL_RETRY_COUNT = "manual_retry_count"
    AVG_ATTEMPT_NUMBER = "avg_attempt_number"
    RATE = "rate"
    SUCCESSFUL_RATE = "successful_rate"
    FAILED_RATE = "failed_rate"


class GetAttemptMetricsMeasuresEnum1(str, Enum):
    COUNT = "count"
    SUCCESSFUL_COUNT = "successful_count"
    FAILED_COUNT = "failed_count"
    ERROR_RATE = "error_rate"
    FIRST_ATTEMPT_COUNT = "first_attempt_count"
    RETRY_COUNT = "retry_count"
    MANUAL_RETRY_COUNT = "manual_retry_count"
    AVG_ATTEMPT_NUMBER = "avg_attempt_number"
    RATE = "rate"
    SUCCESSFUL_RATE = "successful_rate"
    FAILED_RATE = "failed_rate"


GetAttemptMetricsMeasuresUnionTypedDict = TypeAliasType(
    "GetAttemptMetricsMeasuresUnionTypedDict",
    Union[GetAttemptMetricsMeasuresEnum1, List[GetAttemptMetricsMeasuresEnum2]],
)
r"""Measures to compute. At least one required. Rate measures (`rate`, `successful_rate`, `failed_rate`) are throughput in events/second. Use bracket notation for multiple values (e.g., `measures[0]=count&measures[1]=error_rate`)."""


GetAttemptMetricsMeasuresUnion = TypeAliasType(
    "GetAttemptMetricsMeasuresUnion",
    Union[GetAttemptMetricsMeasuresEnum1, List[GetAttemptMetricsMeasuresEnum2]],
)
r"""Measures to compute. At least one required. Rate measures (`rate`, `successful_rate`, `failed_rate`) are throughput in events/second. Use bracket notation for multiple values (e.g., `measures[0]=count&measures[1]=error_rate`)."""


class GetAttemptMetricsDimensionsEnum2(str, Enum):
    TENANT_ID = "tenant_id"
    DESTINATION_ID = "destination_id"
    TOPIC = "topic"
    STATUS = "status"
    CODE = "code"
    MANUAL = "manual"
    ATTEMPT_NUMBER = "attempt_number"


class GetAttemptMetricsDimensionsEnum1(str, Enum):
    TENANT_ID = "tenant_id"
    DESTINATION_ID = "destination_id"
    TOPIC = "topic"
    STATUS = "status"
    CODE = "code"
    MANUAL = "manual"
    ATTEMPT_NUMBER = "attempt_number"


GetAttemptMetricsDimensionsUnionTypedDict = TypeAliasType(
    "GetAttemptMetricsDimensionsUnionTypedDict",
    Union[GetAttemptMetricsDimensionsEnum1, List[GetAttemptMetricsDimensionsEnum2]],
)
r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=status&dimensions[1]=destination_id`)."""


GetAttemptMetricsDimensionsUnion = TypeAliasType(
    "GetAttemptMetricsDimensionsUnion",
    Union[GetAttemptMetricsDimensionsEnum1, List[GetAttemptMetricsDimensionsEnum2]],
)
r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=status&dimensions[1]=destination_id`)."""


GetAttemptMetricsFiltersDestinationIDTypedDict = TypeAliasType(
    "GetAttemptMetricsFiltersDestinationIDTypedDict", Union[str, List[str]]
)
r"""Filter by destination ID(s). Use bracket notation for multiple values (e.g., `filters[destination_id][0]=d1&filters[destination_id][1]=d2`)."""


GetAttemptMetricsFiltersDestinationID = TypeAliasType(
    "GetAttemptMetricsFiltersDestinationID", Union[str, List[str]]
)
r"""Filter by destination ID(s). Use bracket notation for multiple values (e.g., `filters[destination_id][0]=d1&filters[destination_id][1]=d2`)."""


GetAttemptMetricsFiltersTopicTypedDict = TypeAliasType(
    "GetAttemptMetricsFiltersTopicTypedDict", Union[str, List[str]]
)
r"""Filter by topic name(s). Use bracket notation for multiple values (e.g., `filters[topic][0]=user.created&filters[topic][1]=user.updated`)."""


GetAttemptMetricsFiltersTopic = TypeAliasType(
    "GetAttemptMetricsFiltersTopic", Union[str, List[str]]
)
r"""Filter by topic name(s). Use bracket notation for multiple values (e.g., `filters[topic][0]=user.created&filters[topic][1]=user.updated`)."""


class FiltersStatusEnum2(str, Enum):
    SUCCESS = "success"
    FAILED = "failed"


class FiltersStatusEnum1(str, Enum):
    SUCCESS = "success"
    FAILED = "failed"


FiltersStatusTypedDict = TypeAliasType(
    "FiltersStatusTypedDict", Union[FiltersStatusEnum1, List[FiltersStatusEnum2]]
)
r"""Filter by attempt status(es). Use bracket notation for multiple values (e.g., `filters[status][0]=success&filters[status][1]=failed`)."""


FiltersStatus = TypeAliasType(
    "FiltersStatus", Union[FiltersStatusEnum1, List[FiltersStatusEnum2]]
)
r"""Filter by attempt status(es). Use bracket notation for multiple values (e.g., `filters[status][0]=success&filters[status][1]=failed`)."""


FiltersCodeTypedDict = TypeAliasType("FiltersCodeTypedDict", Union[str, List[str]])
r"""Filter by HTTP status code(s). Use bracket notation for multiple values (e.g., `filters[code][0]=200&filters[code][1]=500`)."""


FiltersCode = TypeAliasType("FiltersCode", Union[str, List[str]])
r"""Filter by HTTP status code(s). Use bracket notation for multiple values (e.g., `filters[code][0]=200&filters[code][1]=500`)."""


class FiltersManual(str, Enum):
    r"""Filter by manual retry flag."""

    TRUE = "true"
    FALSE = "false"


FiltersAttemptNumberTypedDict = TypeAliasType(
    "FiltersAttemptNumberTypedDict", Union[str, List[str]]
)
r"""Filter by attempt number(s). Use bracket notation for multiple values (e.g., `filters[attempt_number][0]=1&filters[attempt_number][1]=2`)."""


FiltersAttemptNumber = TypeAliasType("FiltersAttemptNumber", Union[str, List[str]])
r"""Filter by attempt number(s). Use bracket notation for multiple values (e.g., `filters[attempt_number][0]=1&filters[attempt_number][1]=2`)."""


GetAttemptMetricsFiltersTenantIDTypedDict = TypeAliasType(
    "GetAttemptMetricsFiltersTenantIDTypedDict", Union[str, List[str]]
)
r"""Filter by tenant ID(s). Admin-only — rejected with 403 for JWT callers. Use bracket notation for multiple values (e.g., `filters[tenant_id][0]=t1&filters[tenant_id][1]=t2`)."""


GetAttemptMetricsFiltersTenantID = TypeAliasType(
    "GetAttemptMetricsFiltersTenantID", Union[str, List[str]]
)
r"""Filter by tenant ID(s). Admin-only — rejected with 403 for JWT callers. Use bracket notation for multiple values (e.g., `filters[tenant_id][0]=t1&filters[tenant_id][1]=t2`)."""


class GetAttemptMetricsRequestTypedDict(TypedDict):
    time_start: datetime
    r"""Start of the time range (inclusive). ISO 8601 timestamp."""
    time_end: datetime
    r"""End of the time range (exclusive). ISO 8601 timestamp."""
    measures: GetAttemptMetricsMeasuresUnionTypedDict
    r"""Measures to compute. At least one required. Rate measures (`rate`, `successful_rate`, `failed_rate`) are throughput in events/second. Use bracket notation for multiple values (e.g., `measures[0]=count&measures[1]=error_rate`)."""
    granularity: NotRequired[str]
    r"""Time bucketing granularity. Pattern: `<number><unit>`.
    Units: `s` (1-60), `m` (1-60), `h` (1-24), `d` (1-31), `w` (1-4), `M` (1-12).
    When omitted, returns a single aggregate row per dimension combination.

    """
    dimensions: NotRequired[GetAttemptMetricsDimensionsUnionTypedDict]
    r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=status&dimensions[1]=destination_id`)."""
    filters_destination_id: NotRequired[GetAttemptMetricsFiltersDestinationIDTypedDict]
    r"""Filter by destination ID(s). Use bracket notation for multiple values (e.g., `filters[destination_id][0]=d1&filters[destination_id][1]=d2`)."""
    filters_topic: NotRequired[GetAttemptMetricsFiltersTopicTypedDict]
    r"""Filter by topic name(s). Use bracket notation for multiple values (e.g., `filters[topic][0]=user.created&filters[topic][1]=user.updated`)."""
    filters_status: NotRequired[FiltersStatusTypedDict]
    r"""Filter by attempt status(es). Use bracket notation for multiple values (e.g., `filters[status][0]=success&filters[status][1]=failed`)."""
    filters_code: NotRequired[FiltersCodeTypedDict]
    r"""Filter by HTTP status code(s). Use bracket notation for multiple values (e.g., `filters[code][0]=200&filters[code][1]=500`)."""
    filters_manual: NotRequired[FiltersManual]
    r"""Filter by manual retry flag."""
    filters_attempt_number: NotRequired[FiltersAttemptNumberTypedDict]
    r"""Filter by attempt number(s). Use bracket notation for multiple values (e.g., `filters[attempt_number][0]=1&filters[attempt_number][1]=2`)."""
    filters_tenant_id: NotRequired[GetAttemptMetricsFiltersTenantIDTypedDict]
    r"""Filter by tenant ID(s). Admin-only — rejected with 403 for JWT callers. Use bracket notation for multiple values (e.g., `filters[tenant_id][0]=t1&filters[tenant_id][1]=t2`)."""


class GetAttemptMetricsRequest(BaseModel):
    time_start: Annotated[
        datetime,
        pydantic.Field(alias="time[start]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""Start of the time range (inclusive). ISO 8601 timestamp."""

    time_end: Annotated[
        datetime,
        pydantic.Field(alias="time[end]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""End of the time range (exclusive). ISO 8601 timestamp."""

    measures: Annotated[
        GetAttemptMetricsMeasuresUnion,
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""Measures to compute. At least one required. Rate measures (`rate`, `successful_rate`, `failed_rate`) are throughput in events/second. Use bracket notation for multiple values (e.g., `measures[0]=count&measures[1]=error_rate`)."""

    granularity: Annotated[
        Optional[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Time bucketing granularity. Pattern: `<number><unit>`.
    Units: `s` (1-60), `m` (1-60), `h` (1-24), `d` (1-31), `w` (1-4), `M` (1-12).
    When omitted, returns a single aggregate row per dimension combination.

    """

    dimensions: Annotated[
        Optional[GetAttemptMetricsDimensionsUnion],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=status&dimensions[1]=destination_id`)."""

    filters_destination_id: Annotated[
        Optional[GetAttemptMetricsFiltersDestinationID],
        pydantic.Field(alias="filters[destination_id]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by destination ID(s). Use bracket notation for multiple values (e.g., `filters[destination_id][0]=d1&filters[destination_id][1]=d2`)."""

    filters_topic: Annotated[
        Optional[GetAttemptMetricsFiltersTopic],
        pydantic.Field(alias="filters[topic]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by topic name(s). Use bracket notation for multiple values (e.g., `filters[topic][0]=user.created&filters[topic][1]=user.updated`)."""

    filters_status: Annotated[
        Optional[FiltersStatus],
        pydantic.Field(alias="filters[status]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by attempt status(es). Use bracket notation for multiple values (e.g., `filters[status][0]=success&filters[status][1]=failed`)."""

    filters_code: Annotated[
        Optional[FiltersCode],
        pydantic.Field(alias="filters[code]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by HTTP status code(s). Use bracket notation for multiple values (e.g., `filters[code][0]=200&filters[code][1]=500`)."""

    filters_manual: Annotated[
        Optional[FiltersManual],
        pydantic.Field(alias="filters[manual]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by manual retry flag."""

    filters_attempt_number: Annotated[
        Optional[FiltersAttemptNumber],
        pydantic.Field(alias="filters[attempt_number]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by attempt number(s). Use bracket notation for multiple values (e.g., `filters[attempt_number][0]=1&filters[attempt_number][1]=2`)."""

    filters_tenant_id: Annotated[
        Optional[GetAttemptMetricsFiltersTenantID],
        pydantic.Field(alias="filters[tenant_id]"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter by tenant ID(s). Admin-only — rejected with 403 for JWT callers. Use bracket notation for multiple values (e.g., `filters[tenant_id][0]=t1&filters[tenant_id][1]=t2`)."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "granularity",
                "dimensions",
                "filters[destination_id]",
                "filters[topic]",
                "filters[status]",
                "filters[code]",
                "filters[manual]",
                "filters[attempt_number]",
                "filters[tenant_id]",
            ]
        )
        serialized = handler(self)
        m = {}

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

            if val != UNSET_SENTINEL:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m
