"""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 GetEventMetricsMeasuresEnum2(str, Enum):
    COUNT = "count"
    RATE = "rate"


class GetEventMetricsMeasuresEnum1(str, Enum):
    COUNT = "count"
    RATE = "rate"


GetEventMetricsMeasuresUnionTypedDict = TypeAliasType(
    "GetEventMetricsMeasuresUnionTypedDict",
    Union[GetEventMetricsMeasuresEnum1, List[GetEventMetricsMeasuresEnum2]],
)
r"""Measures to compute. At least one required. `rate` is events/second throughput. Use bracket notation for multiple values (e.g., `measures[0]=count`)."""


GetEventMetricsMeasuresUnion = TypeAliasType(
    "GetEventMetricsMeasuresUnion",
    Union[GetEventMetricsMeasuresEnum1, List[GetEventMetricsMeasuresEnum2]],
)
r"""Measures to compute. At least one required. `rate` is events/second throughput. Use bracket notation for multiple values (e.g., `measures[0]=count`)."""


class GetEventMetricsDimensionsEnum2(str, Enum):
    TENANT_ID = "tenant_id"
    TOPIC = "topic"
    DESTINATION_ID = "destination_id"


class GetEventMetricsDimensionsEnum1(str, Enum):
    TENANT_ID = "tenant_id"
    TOPIC = "topic"
    DESTINATION_ID = "destination_id"


GetEventMetricsDimensionsUnionTypedDict = TypeAliasType(
    "GetEventMetricsDimensionsUnionTypedDict",
    Union[GetEventMetricsDimensionsEnum1, List[GetEventMetricsDimensionsEnum2]],
)
r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=topic&dimensions[1]=destination_id`)."""


GetEventMetricsDimensionsUnion = TypeAliasType(
    "GetEventMetricsDimensionsUnion",
    Union[GetEventMetricsDimensionsEnum1, List[GetEventMetricsDimensionsEnum2]],
)
r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=topic&dimensions[1]=destination_id`)."""


GetEventMetricsFiltersTopicTypedDict = TypeAliasType(
    "GetEventMetricsFiltersTopicTypedDict", 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`)."""


GetEventMetricsFiltersTopic = TypeAliasType(
    "GetEventMetricsFiltersTopic", 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`)."""


GetEventMetricsFiltersDestinationIDTypedDict = TypeAliasType(
    "GetEventMetricsFiltersDestinationIDTypedDict", 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`)."""


GetEventMetricsFiltersDestinationID = TypeAliasType(
    "GetEventMetricsFiltersDestinationID", 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`)."""


GetEventMetricsFiltersTenantIDTypedDict = TypeAliasType(
    "GetEventMetricsFiltersTenantIDTypedDict", 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`)."""


GetEventMetricsFiltersTenantID = TypeAliasType(
    "GetEventMetricsFiltersTenantID", 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 GetEventMetricsRequestTypedDict(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: GetEventMetricsMeasuresUnionTypedDict
    r"""Measures to compute. At least one required. `rate` is events/second throughput. Use bracket notation for multiple values (e.g., `measures[0]=count`)."""
    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[GetEventMetricsDimensionsUnionTypedDict]
    r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=topic&dimensions[1]=destination_id`)."""
    filters_topic: NotRequired[GetEventMetricsFiltersTopicTypedDict]
    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_destination_id: NotRequired[GetEventMetricsFiltersDestinationIDTypedDict]
    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_tenant_id: NotRequired[GetEventMetricsFiltersTenantIDTypedDict]
    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 GetEventMetricsRequest(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[
        GetEventMetricsMeasuresUnion,
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""Measures to compute. At least one required. `rate` is events/second throughput. Use bracket notation for multiple values (e.g., `measures[0]=count`)."""

    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[GetEventMetricsDimensionsUnion],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Dimensions to group results by. Use bracket notation for multiple values (e.g., `dimensions[0]=topic&dimensions[1]=destination_id`)."""

    filters_topic: Annotated[
        Optional[GetEventMetricsFiltersTopic],
        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_destination_id: Annotated[
        Optional[GetEventMetricsFiltersDestinationID],
        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_tenant_id: Annotated[
        Optional[GetEventMetricsFiltersTenantID],
        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[topic]",
                "filters[destination_id]",
                "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
