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

from __future__ import annotations
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


UpsertPartnerLinkTagIdsTypedDict = TypeAliasType(
    "UpsertPartnerLinkTagIdsTypedDict", Union[str, List[str]]
)
r"""The unique IDs of the tags assigned to the short link."""


UpsertPartnerLinkTagIds = TypeAliasType(
    "UpsertPartnerLinkTagIds", Union[str, List[str]]
)
r"""The unique IDs of the tags assigned to the short link."""


UpsertPartnerLinkTagNamesTypedDict = TypeAliasType(
    "UpsertPartnerLinkTagNamesTypedDict", Union[str, List[str]]
)
r"""The unique name of the tags assigned to the short link (case insensitive)."""


UpsertPartnerLinkTagNames = TypeAliasType(
    "UpsertPartnerLinkTagNames", Union[str, List[str]]
)
r"""The unique name of the tags assigned to the short link (case insensitive)."""


class UpsertPartnerLinkTestVariantsTypedDict(TypedDict):
    url: str
    percentage: float


class UpsertPartnerLinkTestVariants(BaseModel):
    url: str

    percentage: float


class UpsertPartnerLinkLinkPropsTypedDict(TypedDict):
    r"""Additional properties that you can pass to the partner's short link. Will be used to override the default link properties for this partner."""

    key_length: NotRequired[float]
    r"""The length of the short link slug. Defaults to 7 if not provided. When used with `prefix`, the total length of the key will be `prefix.length + keyLength`."""
    external_id: NotRequired[Nullable[str]]
    r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
    tenant_id: NotRequired[Nullable[str]]
    r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
    prefix: NotRequired[str]
    r"""The prefix of the short link slug for randomly-generated keys (e.g. if prefix is `/c/`, generated keys will be in the `/c/:key` format). Will be ignored if `key` is provided."""
    archived: NotRequired[bool]
    r"""Whether the short link is archived. Defaults to `false` if not provided."""
    tag_ids: NotRequired[UpsertPartnerLinkTagIdsTypedDict]
    r"""The unique IDs of the tags assigned to the short link."""
    tag_names: NotRequired[UpsertPartnerLinkTagNamesTypedDict]
    r"""The unique name of the tags assigned to the short link (case insensitive)."""
    comments: NotRequired[Nullable[str]]
    r"""The comments for the short link."""
    expires_at: NotRequired[Nullable[str]]
    r"""The date and time when the short link will expire at."""
    expired_url: NotRequired[Nullable[str]]
    r"""The URL to redirect to when the short link has expired."""
    password: NotRequired[Nullable[str]]
    r"""The password required to access the destination URL of the short link."""
    proxy: NotRequired[bool]
    r"""Whether the short link uses Custom Link Previews feature. Defaults to `false` if not provided."""
    title: NotRequired[Nullable[str]]
    r"""The custom link preview title (og:title). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
    description: NotRequired[Nullable[str]]
    r"""The custom link preview description (og:description). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
    image: NotRequired[Nullable[str]]
    r"""The custom link preview image (og:image). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
    video: NotRequired[Nullable[str]]
    r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
    rewrite: NotRequired[bool]
    r"""Whether the short link uses link cloaking. Defaults to `false` if not provided."""
    ios: NotRequired[Nullable[str]]
    r"""The iOS destination URL for the short link for iOS device targeting."""
    android: NotRequired[Nullable[str]]
    r"""The Android destination URL for the short link for Android device targeting."""
    do_index: NotRequired[bool]
    r"""Allow search engines to index your short link. Defaults to `false` if not provided. Learn more: https://d.to/noindex"""
    test_variants: NotRequired[Nullable[List[UpsertPartnerLinkTestVariantsTypedDict]]]
    r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
    test_started_at: NotRequired[Nullable[str]]
    r"""The date and time when the tests started."""
    test_completed_at: NotRequired[Nullable[str]]
    r"""The date and time when the tests were or will be completed."""


class UpsertPartnerLinkLinkProps(BaseModel):
    r"""Additional properties that you can pass to the partner's short link. Will be used to override the default link properties for this partner."""

    key_length: Annotated[Optional[float], pydantic.Field(alias="keyLength")] = None
    r"""The length of the short link slug. Defaults to 7 if not provided. When used with `prefix`, the total length of the key will be `prefix.length + keyLength`."""

    external_id: Annotated[
        OptionalNullable[str], pydantic.Field(alias="externalId")
    ] = UNSET
    r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""

    tenant_id: Annotated[OptionalNullable[str], pydantic.Field(alias="tenantId")] = (
        UNSET
    )
    r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""

    prefix: Optional[str] = None
    r"""The prefix of the short link slug for randomly-generated keys (e.g. if prefix is `/c/`, generated keys will be in the `/c/:key` format). Will be ignored if `key` is provided."""

    archived: Optional[bool] = None
    r"""Whether the short link is archived. Defaults to `false` if not provided."""

    tag_ids: Annotated[
        Optional[UpsertPartnerLinkTagIds], pydantic.Field(alias="tagIds")
    ] = None
    r"""The unique IDs of the tags assigned to the short link."""

    tag_names: Annotated[
        Optional[UpsertPartnerLinkTagNames], pydantic.Field(alias="tagNames")
    ] = None
    r"""The unique name of the tags assigned to the short link (case insensitive)."""

    comments: OptionalNullable[str] = UNSET
    r"""The comments for the short link."""

    expires_at: Annotated[OptionalNullable[str], pydantic.Field(alias="expiresAt")] = (
        UNSET
    )
    r"""The date and time when the short link will expire at."""

    expired_url: Annotated[
        OptionalNullable[str], pydantic.Field(alias="expiredUrl")
    ] = UNSET
    r"""The URL to redirect to when the short link has expired."""

    password: OptionalNullable[str] = UNSET
    r"""The password required to access the destination URL of the short link."""

    proxy: Optional[bool] = None
    r"""Whether the short link uses Custom Link Previews feature. Defaults to `false` if not provided."""

    title: OptionalNullable[str] = UNSET
    r"""The custom link preview title (og:title). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""

    description: OptionalNullable[str] = UNSET
    r"""The custom link preview description (og:description). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""

    image: OptionalNullable[str] = UNSET
    r"""The custom link preview image (og:image). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""

    video: OptionalNullable[str] = UNSET
    r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""

    rewrite: Optional[bool] = None
    r"""Whether the short link uses link cloaking. Defaults to `false` if not provided."""

    ios: OptionalNullable[str] = UNSET
    r"""The iOS destination URL for the short link for iOS device targeting."""

    android: OptionalNullable[str] = UNSET
    r"""The Android destination URL for the short link for Android device targeting."""

    do_index: Annotated[Optional[bool], pydantic.Field(alias="doIndex")] = None
    r"""Allow search engines to index your short link. Defaults to `false` if not provided. Learn more: https://d.to/noindex"""

    test_variants: Annotated[
        OptionalNullable[List[UpsertPartnerLinkTestVariants]],
        pydantic.Field(alias="testVariants"),
    ] = UNSET
    r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""

    test_started_at: Annotated[
        OptionalNullable[str], pydantic.Field(alias="testStartedAt")
    ] = UNSET
    r"""The date and time when the tests started."""

    test_completed_at: Annotated[
        OptionalNullable[str], pydantic.Field(alias="testCompletedAt")
    ] = UNSET
    r"""The date and time when the tests were or will be completed."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "keyLength",
                "externalId",
                "tenantId",
                "prefix",
                "archived",
                "tagIds",
                "tagNames",
                "comments",
                "expiresAt",
                "expiredUrl",
                "password",
                "proxy",
                "title",
                "description",
                "image",
                "video",
                "rewrite",
                "ios",
                "android",
                "doIndex",
                "testVariants",
                "testStartedAt",
                "testCompletedAt",
            ]
        )
        nullable_fields = set(
            [
                "externalId",
                "tenantId",
                "comments",
                "expiresAt",
                "expiredUrl",
                "password",
                "title",
                "description",
                "image",
                "video",
                "ios",
                "android",
                "testVariants",
                "testStartedAt",
                "testCompletedAt",
            ]
        )
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

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

        return m


class UpsertPartnerLinkRequestBodyTypedDict(TypedDict):
    url: str
    r"""The URL to upsert for. Will throw an error if the domain doesn't match the program's default URL domain."""
    partner_id: NotRequired[Nullable[str]]
    r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
    tenant_id: NotRequired[Nullable[str]]
    r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
    key: NotRequired[str]
    r"""The short link slug. If not provided, a random 7-character slug will be generated."""
    comments: NotRequired[Nullable[str]]
    r"""The comments for the short link."""
    link_props: NotRequired[UpsertPartnerLinkLinkPropsTypedDict]
    r"""Additional properties that you can pass to the partner's short link. Will be used to override the default link properties for this partner."""


class UpsertPartnerLinkRequestBody(BaseModel):
    url: str
    r"""The URL to upsert for. Will throw an error if the domain doesn't match the program's default URL domain."""

    partner_id: Annotated[OptionalNullable[str], pydantic.Field(alias="partnerId")] = (
        UNSET
    )
    r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""

    tenant_id: Annotated[OptionalNullable[str], pydantic.Field(alias="tenantId")] = (
        UNSET
    )
    r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""

    key: Optional[str] = None
    r"""The short link slug. If not provided, a random 7-character slug will be generated."""

    comments: OptionalNullable[str] = UNSET
    r"""The comments for the short link."""

    link_props: Annotated[
        Optional[UpsertPartnerLinkLinkProps], pydantic.Field(alias="linkProps")
    ] = None
    r"""Additional properties that you can pass to the partner's short link. Will be used to override the default link properties for this partner."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["partnerId", "tenantId", "key", "comments", "linkProps"])
        nullable_fields = set(["partnerId", "tenantId", "comments"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

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

        return m
