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

from __future__ import annotations
from .httpmetadata import HTTPMetadata, HTTPMetadataTypedDict
from enum import Enum
import pydantic
from pydantic import model_serializer
from typing import Any, Dict, List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict, deprecated
from unkey_py.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL


@deprecated(
    "warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
)
class UpdateKeyType(str, Enum):
    r"""Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.
    Deprecated, use 'async' instead
    https://unkey.dev/docs/features/ratelimiting - Learn more
    """

    FAST = "fast"
    CONSISTENT = "consistent"


class UpdateKeyRatelimitTypedDict(TypedDict):
    r"""Unkey comes with per-key ratelimiting out of the box. Set `null` to disable."""

    limit: int
    r"""The total amount of requests allowed in a single window."""
    type: NotRequired[UpdateKeyType]
    r"""Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.
    Deprecated, use 'async' instead
    https://unkey.dev/docs/features/ratelimiting - Learn more
    """
    async_: NotRequired[bool]
    r"""Asnyc ratelimiting doesn't add latency, while sync ratelimiting is slightly more accurate.
    https://unkey.dev/docs/features/ratelimiting - Learn more
    """
    refill_rate: NotRequired[int]
    r"""How many tokens to refill during each refillInterval.
    Deprecated, use 'limit' instead.
    """
    refill_interval: NotRequired[int]
    r"""Determines the speed at which tokens are refilled, in milliseconds.
    Deprecated, use 'duration'
    """
    duration: NotRequired[int]
    r"""The duration of each ratelimit window, in milliseconds.
    This field will become required in a future version.
    """


class UpdateKeyRatelimit(BaseModel):
    r"""Unkey comes with per-key ratelimiting out of the box. Set `null` to disable."""

    limit: int
    r"""The total amount of requests allowed in a single window."""

    type: Annotated[
        Optional[UpdateKeyType],
        pydantic.Field(
            deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
        ),
    ] = None
    r"""Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.
    Deprecated, use 'async' instead
    https://unkey.dev/docs/features/ratelimiting - Learn more
    """

    async_: Annotated[Optional[bool], pydantic.Field(alias="async")] = False
    r"""Asnyc ratelimiting doesn't add latency, while sync ratelimiting is slightly more accurate.
    https://unkey.dev/docs/features/ratelimiting - Learn more
    """

    refill_rate: Annotated[
        Optional[int],
        pydantic.Field(
            deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
            alias="refillRate",
        ),
    ] = None
    r"""How many tokens to refill during each refillInterval.
    Deprecated, use 'limit' instead.
    """

    refill_interval: Annotated[
        Optional[int],
        pydantic.Field(
            deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
            alias="refillInterval",
        ),
    ] = None
    r"""Determines the speed at which tokens are refilled, in milliseconds.
    Deprecated, use 'duration'
    """

    duration: Optional[int] = None
    r"""The duration of each ratelimit window, in milliseconds.
    This field will become required in a future version.
    """


class UpdateKeyInterval(str, Enum):
    r"""Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key."""

    DAILY = "daily"
    MONTHLY = "monthly"


class UpdateKeyRefillTypedDict(TypedDict):
    r"""Unkey enables you to refill verifications for each key at regular intervals."""

    interval: UpdateKeyInterval
    r"""Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key."""
    amount: int
    r"""The amount of verifications to refill for each occurrence is determined individually for each key."""
    refill_day: NotRequired[float]
    r"""The day verifications will refill each month, when interval is set to 'monthly'"""


class UpdateKeyRefill(BaseModel):
    r"""Unkey enables you to refill verifications for each key at regular intervals."""

    interval: UpdateKeyInterval
    r"""Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key."""

    amount: int
    r"""The amount of verifications to refill for each occurrence is determined individually for each key."""

    refill_day: Annotated[Optional[float], pydantic.Field(alias="refillDay")] = None
    r"""The day verifications will refill each month, when interval is set to 'monthly'"""


class RolesTypedDict(TypedDict):
    id: NotRequired[str]
    r"""The id of the role. Provide either `id` or `name`. If both are provided `id` is used."""
    name: NotRequired[str]
    r"""Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used."""
    create: NotRequired[bool]
    r"""Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`.
    Autocreating roles requires your root key to have the `rbac.*.create_role` permission, otherwise the request will get rejected
    """


class Roles(BaseModel):
    id: Optional[str] = None
    r"""The id of the role. Provide either `id` or `name`. If both are provided `id` is used."""

    name: Optional[str] = None
    r"""Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used."""

    create: Optional[bool] = None
    r"""Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`.
    Autocreating roles requires your root key to have the `rbac.*.create_role` permission, otherwise the request will get rejected
    """


class UpdateKeyPermissionsTypedDict(TypedDict):
    id: NotRequired[str]
    r"""The id of the permission. Provide either `id` or `name`. If both are provided `id` is used."""
    name: NotRequired[str]
    r"""Identify the permission via its name. Provide either `id` or `name`. If both are provided `id` is used."""
    create: NotRequired[bool]
    r"""Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`.
    Autocreating permissions requires your root key to have the `rbac.*.create_permission` permission, otherwise the request will get rejected
    """


class UpdateKeyPermissions(BaseModel):
    id: Optional[str] = None
    r"""The id of the permission. Provide either `id` or `name`. If both are provided `id` is used."""

    name: Optional[str] = None
    r"""Identify the permission via its name. Provide either `id` or `name`. If both are provided `id` is used."""

    create: Optional[bool] = None
    r"""Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`.
    Autocreating permissions requires your root key to have the `rbac.*.create_permission` permission, otherwise the request will get rejected
    """


class UpdateKeyRequestBodyTypedDict(TypedDict):
    r"""Update a key's configuration.
    The `apis.<API_ID>.update_key` permission is required.
    """

    key_id: str
    r"""The id of the key you want to modify"""
    name: NotRequired[Nullable[str]]
    r"""The name of the key"""
    owner_id: NotRequired[Nullable[str]]
    r"""Deprecated, use `externalId`
    The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
    """
    external_id: NotRequired[Nullable[str]]
    r"""The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this back to you, so you know who is accessing your API.
    Under the hood this upserts and connects an `ìdentity` for you.
    To disconnect the key from an identity, set `externalId: null`.
    """
    meta: NotRequired[Nullable[Dict[str, Nullable[Any]]]]
    r"""Any additional metadata you want to store with the key"""
    expires: NotRequired[Nullable[int]]
    r"""The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring."""
    ratelimit: NotRequired[Nullable[UpdateKeyRatelimitTypedDict]]
    r"""Unkey comes with per-key ratelimiting out of the box. Set `null` to disable."""
    remaining: NotRequired[Nullable[int]]
    r"""The number of requests that can be made with this key before it becomes invalid. Set `null` to disable."""
    refill: NotRequired[Nullable[UpdateKeyRefillTypedDict]]
    r"""Unkey enables you to refill verifications for each key at regular intervals."""
    enabled: NotRequired[bool]
    r"""Set if key is enabled or disabled. If disabled, the key cannot be used to verify."""
    roles: NotRequired[List[RolesTypedDict]]
    r"""The roles you want to set for this key. This overwrites all existing roles.
    Setting roles requires the `rbac.*.add_role_to_key` permission.
    """
    permissions: NotRequired[List[UpdateKeyPermissionsTypedDict]]
    r"""The permissions you want to set for this key. This overwrites all existing permissions.
    Setting permissions requires the `rbac.*.add_permission_to_key` permission.
    """


class UpdateKeyRequestBody(BaseModel):
    r"""Update a key's configuration.
    The `apis.<API_ID>.update_key` permission is required.
    """

    key_id: Annotated[str, pydantic.Field(alias="keyId")]
    r"""The id of the key you want to modify"""

    name: OptionalNullable[str] = UNSET
    r"""The name of the key"""

    owner_id: Annotated[
        OptionalNullable[str],
        pydantic.Field(
            deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
            alias="ownerId",
        ),
    ] = UNSET
    r"""Deprecated, use `externalId`
    The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
    """

    external_id: Annotated[
        OptionalNullable[str], pydantic.Field(alias="externalId")
    ] = UNSET
    r"""The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this back to you, so you know who is accessing your API.
    Under the hood this upserts and connects an `ìdentity` for you.
    To disconnect the key from an identity, set `externalId: null`.
    """

    meta: OptionalNullable[Dict[str, Nullable[Any]]] = UNSET
    r"""Any additional metadata you want to store with the key"""

    expires: OptionalNullable[int] = UNSET
    r"""The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring."""

    ratelimit: OptionalNullable[UpdateKeyRatelimit] = UNSET
    r"""Unkey comes with per-key ratelimiting out of the box. Set `null` to disable."""

    remaining: OptionalNullable[int] = UNSET
    r"""The number of requests that can be made with this key before it becomes invalid. Set `null` to disable."""

    refill: OptionalNullable[UpdateKeyRefill] = UNSET
    r"""Unkey enables you to refill verifications for each key at regular intervals."""

    enabled: Optional[bool] = None
    r"""Set if key is enabled or disabled. If disabled, the key cannot be used to verify."""

    roles: Optional[List[Roles]] = None
    r"""The roles you want to set for this key. This overwrites all existing roles.
    Setting roles requires the `rbac.*.add_role_to_key` permission.
    """

    permissions: Optional[List[UpdateKeyPermissions]] = None
    r"""The permissions you want to set for this key. This overwrites all existing permissions.
    Setting permissions requires the `rbac.*.add_permission_to_key` permission.
    """

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "name",
            "ownerId",
            "externalId",
            "meta",
            "expires",
            "ratelimit",
            "remaining",
            "refill",
            "enabled",
            "roles",
            "permissions",
        ]
        nullable_fields = [
            "name",
            "ownerId",
            "externalId",
            "meta",
            "expires",
            "ratelimit",
            "remaining",
            "refill",
        ]
        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


class UpdateKeyResponseBodyTypedDict(TypedDict):
    r"""The key was successfully updated, it may take up to 30s for this to take effect in all regions"""


class UpdateKeyResponseBody(BaseModel):
    r"""The key was successfully updated, it may take up to 30s for this to take effect in all regions"""


class UpdateKeyResponseTypedDict(TypedDict):
    http_meta: HTTPMetadataTypedDict
    object: NotRequired[UpdateKeyResponseBodyTypedDict]
    r"""The key was successfully updated, it may take up to 30s for this to take effect in all regions"""


class UpdateKeyResponse(BaseModel):
    http_meta: Annotated[Optional[HTTPMetadata], pydantic.Field(exclude=True)] = None

    object: Optional[UpdateKeyResponseBody] = None
    r"""The key was successfully updated, it may take up to 30s for this to take effect in all regions"""
