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

from __future__ import annotations
from .diffsummarydto import DiffSummaryDto, DiffSummaryDtoTypedDict
from .resourcedependencydto import ResourceDependencyDto, ResourceDependencyDtoTypedDict
from .resourcediffdto import ResourceDiffDto, ResourceDiffDtoTypedDict
from .resourcetypeenum import ResourceTypeEnum
from datetime import datetime
from novu_py.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class ResourceDiffResultDtoSourceResourceUpdatedByTypedDict(TypedDict):
    r"""User who last updated the resource"""

    id: str
    r"""User ID"""
    first_name: str
    r"""User first name"""
    last_name: NotRequired[Nullable[str]]
    r"""User last name"""
    external_id: NotRequired[str]
    r"""User external ID"""


class ResourceDiffResultDtoSourceResourceUpdatedBy(BaseModel):
    r"""User who last updated the resource"""

    id: Annotated[str, pydantic.Field(alias="_id")]
    r"""User ID"""

    first_name: Annotated[str, pydantic.Field(alias="firstName")]
    r"""User first name"""

    last_name: Annotated[OptionalNullable[str], pydantic.Field(alias="lastName")] = (
        UNSET
    )
    r"""User last name"""

    external_id: Annotated[Optional[str], pydantic.Field(alias="externalId")] = None
    r"""User external ID"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["lastName", "externalId"])
        nullable_fields = set(["lastName"])
        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 SourceResourceTypedDict(TypedDict):
    r"""Source resource information"""

    id: NotRequired[Nullable[str]]
    r"""Resource ID (workflow ID or step ID)"""
    name: NotRequired[Nullable[str]]
    r"""Resource name (workflow name or step name)"""
    updated_by: NotRequired[
        Nullable[ResourceDiffResultDtoSourceResourceUpdatedByTypedDict]
    ]
    r"""User who last updated the resource"""
    updated_at: NotRequired[Nullable[datetime]]
    r"""When the resource was last updated"""


class SourceResource(BaseModel):
    r"""Source resource information"""

    id: OptionalNullable[str] = UNSET
    r"""Resource ID (workflow ID or step ID)"""

    name: OptionalNullable[str] = UNSET
    r"""Resource name (workflow name or step name)"""

    updated_by: Annotated[
        OptionalNullable[ResourceDiffResultDtoSourceResourceUpdatedBy],
        pydantic.Field(alias="updatedBy"),
    ] = UNSET
    r"""User who last updated the resource"""

    updated_at: Annotated[
        OptionalNullable[datetime], pydantic.Field(alias="updatedAt")
    ] = UNSET
    r"""When the resource was last updated"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["id", "name", "updatedBy", "updatedAt"])
        nullable_fields = set(["id", "name", "updatedBy", "updatedAt"])
        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 ResourceDiffResultDtoUpdatedByTypedDict(TypedDict):
    r"""User who last updated the resource"""

    id: str
    r"""User ID"""
    first_name: str
    r"""User first name"""
    last_name: NotRequired[Nullable[str]]
    r"""User last name"""
    external_id: NotRequired[str]
    r"""User external ID"""


class ResourceDiffResultDtoUpdatedBy(BaseModel):
    r"""User who last updated the resource"""

    id: Annotated[str, pydantic.Field(alias="_id")]
    r"""User ID"""

    first_name: Annotated[str, pydantic.Field(alias="firstName")]
    r"""User first name"""

    last_name: Annotated[OptionalNullable[str], pydantic.Field(alias="lastName")] = (
        UNSET
    )
    r"""User last name"""

    external_id: Annotated[Optional[str], pydantic.Field(alias="externalId")] = None
    r"""User external ID"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["lastName", "externalId"])
        nullable_fields = set(["lastName"])
        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 TargetResourceTypedDict(TypedDict):
    r"""Target resource information"""

    id: NotRequired[Nullable[str]]
    r"""Resource ID (workflow ID or step ID)"""
    name: NotRequired[Nullable[str]]
    r"""Resource name (workflow name or step name)"""
    updated_by: NotRequired[Nullable[ResourceDiffResultDtoUpdatedByTypedDict]]
    r"""User who last updated the resource"""
    updated_at: NotRequired[Nullable[datetime]]
    r"""When the resource was last updated"""


class TargetResource(BaseModel):
    r"""Target resource information"""

    id: OptionalNullable[str] = UNSET
    r"""Resource ID (workflow ID or step ID)"""

    name: OptionalNullable[str] = UNSET
    r"""Resource name (workflow name or step name)"""

    updated_by: Annotated[
        OptionalNullable[ResourceDiffResultDtoUpdatedBy],
        pydantic.Field(alias="updatedBy"),
    ] = UNSET
    r"""User who last updated the resource"""

    updated_at: Annotated[
        OptionalNullable[datetime], pydantic.Field(alias="updatedAt")
    ] = UNSET
    r"""When the resource was last updated"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["id", "name", "updatedBy", "updatedAt"])
        nullable_fields = set(["id", "name", "updatedBy", "updatedAt"])
        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 ResourceDiffResultDtoTypedDict(TypedDict):
    resource_type: ResourceTypeEnum
    r"""Type of the layout"""
    changes: List[ResourceDiffDtoTypedDict]
    r"""List of specific changes for this resource"""
    summary: DiffSummaryDtoTypedDict
    r"""Summary of changes for this resource"""
    source_resource: NotRequired[Nullable[SourceResourceTypedDict]]
    r"""Source resource information"""
    target_resource: NotRequired[Nullable[TargetResourceTypedDict]]
    r"""Target resource information"""
    dependencies: NotRequired[List[ResourceDependencyDtoTypedDict]]
    r"""Dependencies that affect this resource"""


class ResourceDiffResultDto(BaseModel):
    resource_type: Annotated[ResourceTypeEnum, pydantic.Field(alias="resourceType")]
    r"""Type of the layout"""

    changes: List[ResourceDiffDto]
    r"""List of specific changes for this resource"""

    summary: DiffSummaryDto
    r"""Summary of changes for this resource"""

    source_resource: Annotated[
        OptionalNullable[SourceResource], pydantic.Field(alias="sourceResource")
    ] = UNSET
    r"""Source resource information"""

    target_resource: Annotated[
        OptionalNullable[TargetResource], pydantic.Field(alias="targetResource")
    ] = UNSET
    r"""Target resource information"""

    dependencies: Optional[List[ResourceDependencyDto]] = None
    r"""Dependencies that affect this resource"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["sourceResource", "targetResource", "dependencies"])
        nullable_fields = set(["sourceResource", "targetResource"])
        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


try:
    ResourceDiffResultDtoSourceResourceUpdatedBy.model_rebuild()
except NameError:
    pass
try:
    SourceResource.model_rebuild()
except NameError:
    pass
try:
    ResourceDiffResultDtoUpdatedBy.model_rebuild()
except NameError:
    pass
try:
    TargetResource.model_rebuild()
except NameError:
    pass
try:
    ResourceDiffResultDto.model_rebuild()
except NameError:
    pass
