# coding: utf-8

"""
Immich

Immich API

The version of the OpenAPI document: 2.4.1
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""  # noqa: E501

from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from immich.client.models.asset_face_without_person_response_dto import (
    AssetFaceWithoutPersonResponseDto,
)
from immich.client.models.asset_stack_response_dto import AssetStackResponseDto
from immich.client.models.asset_type_enum import AssetTypeEnum
from immich.client.models.asset_visibility import AssetVisibility
from immich.client.models.exif_response_dto import ExifResponseDto
from immich.client.models.person_with_faces_response_dto import (
    PersonWithFacesResponseDto,
)
from immich.client.models.tag_response_dto import TagResponseDto
from immich.client.models.user_response_dto import UserResponseDto
from typing import Set
from typing_extensions import Self


class AssetResponseDto(BaseModel):
    """
    AssetResponseDto
    """  # noqa: E501

    checksum: StrictStr = Field(description="base64 encoded sha1 hash")
    created_at: datetime = Field(
        description="The UTC timestamp when the asset was originally uploaded to Immich.",
        alias="createdAt",
    )
    device_asset_id: StrictStr = Field(alias="deviceAssetId")
    device_id: StrictStr = Field(alias="deviceId")
    duplicate_id: Optional[StrictStr] = Field(default=None, alias="duplicateId")
    duration: StrictStr
    exif_info: Optional[ExifResponseDto] = Field(default=None, alias="exifInfo")
    file_created_at: datetime = Field(
        description="The actual UTC timestamp when the file was created/captured, preserving timezone information. This is the authoritative timestamp for chronological sorting within timeline groups. Combined with timezone data, this can be used to determine the exact moment the photo was taken.",
        alias="fileCreatedAt",
    )
    file_modified_at: datetime = Field(
        description="The UTC timestamp when the file was last modified on the filesystem. This reflects the last time the physical file was changed, which may be different from when the photo was originally taken.",
        alias="fileModifiedAt",
    )
    has_metadata: StrictBool = Field(alias="hasMetadata")
    id: StrictStr
    is_archived: StrictBool = Field(alias="isArchived")
    is_favorite: StrictBool = Field(alias="isFavorite")
    is_offline: StrictBool = Field(alias="isOffline")
    is_trashed: StrictBool = Field(alias="isTrashed")
    library_id: Optional[StrictStr] = Field(default=None, alias="libraryId")
    live_photo_video_id: Optional[StrictStr] = Field(
        default=None, alias="livePhotoVideoId"
    )
    local_date_time: datetime = Field(
        description='The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer\'s local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by "local" days and months.',
        alias="localDateTime",
    )
    original_file_name: StrictStr = Field(alias="originalFileName")
    original_mime_type: Optional[StrictStr] = Field(
        default=None, alias="originalMimeType"
    )
    original_path: StrictStr = Field(alias="originalPath")
    owner: Optional[UserResponseDto] = None
    owner_id: StrictStr = Field(alias="ownerId")
    people: Optional[List[PersonWithFacesResponseDto]] = None
    resized: Optional[StrictBool] = None
    stack: Optional[AssetStackResponseDto] = None
    tags: Optional[List[TagResponseDto]] = None
    thumbhash: Optional[StrictStr]
    type: AssetTypeEnum
    unassigned_faces: Optional[List[AssetFaceWithoutPersonResponseDto]] = Field(
        default=None, alias="unassignedFaces"
    )
    updated_at: datetime = Field(
        description="The UTC timestamp when the asset record was last updated in the database. This is automatically maintained by the database and reflects when any field in the asset was last modified.",
        alias="updatedAt",
    )
    visibility: AssetVisibility
    __properties: ClassVar[List[str]] = [
        "checksum",
        "createdAt",
        "deviceAssetId",
        "deviceId",
        "duplicateId",
        "duration",
        "exifInfo",
        "fileCreatedAt",
        "fileModifiedAt",
        "hasMetadata",
        "id",
        "isArchived",
        "isFavorite",
        "isOffline",
        "isTrashed",
        "libraryId",
        "livePhotoVideoId",
        "localDateTime",
        "originalFileName",
        "originalMimeType",
        "originalPath",
        "owner",
        "ownerId",
        "people",
        "resized",
        "stack",
        "tags",
        "thumbhash",
        "type",
        "unassignedFaces",
        "updatedAt",
        "visibility",
    ]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of AssetResponseDto from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of exif_info
        if self.exif_info:
            _dict["exifInfo"] = self.exif_info.to_dict()
        # override the default output from pydantic by calling `to_dict()` of owner
        if self.owner:
            _dict["owner"] = self.owner.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in people (list)
        _items = []
        if self.people:
            for _item_people in self.people:
                if _item_people:
                    _items.append(_item_people.to_dict())
            _dict["people"] = _items
        # override the default output from pydantic by calling `to_dict()` of stack
        if self.stack:
            _dict["stack"] = self.stack.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in tags (list)
        _items = []
        if self.tags:
            for _item_tags in self.tags:
                if _item_tags:
                    _items.append(_item_tags.to_dict())
            _dict["tags"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in unassigned_faces (list)
        _items = []
        if self.unassigned_faces:
            for _item_unassigned_faces in self.unassigned_faces:
                if _item_unassigned_faces:
                    _items.append(_item_unassigned_faces.to_dict())
            _dict["unassignedFaces"] = _items
        # set to None if duplicate_id (nullable) is None
        # and model_fields_set contains the field
        if self.duplicate_id is None and "duplicate_id" in self.model_fields_set:
            _dict["duplicateId"] = None

        # set to None if library_id (nullable) is None
        # and model_fields_set contains the field
        if self.library_id is None and "library_id" in self.model_fields_set:
            _dict["libraryId"] = None

        # set to None if live_photo_video_id (nullable) is None
        # and model_fields_set contains the field
        if (
            self.live_photo_video_id is None
            and "live_photo_video_id" in self.model_fields_set
        ):
            _dict["livePhotoVideoId"] = None

        # set to None if stack (nullable) is None
        # and model_fields_set contains the field
        if self.stack is None and "stack" in self.model_fields_set:
            _dict["stack"] = None

        # set to None if thumbhash (nullable) is None
        # and model_fields_set contains the field
        if self.thumbhash is None and "thumbhash" in self.model_fields_set:
            _dict["thumbhash"] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of AssetResponseDto from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate(
            {
                "checksum": obj.get("checksum"),
                "createdAt": obj.get("createdAt"),
                "deviceAssetId": obj.get("deviceAssetId"),
                "deviceId": obj.get("deviceId"),
                "duplicateId": obj.get("duplicateId"),
                "duration": obj.get("duration"),
                "exifInfo": ExifResponseDto.from_dict(obj["exifInfo"])
                if obj.get("exifInfo") is not None
                else None,
                "fileCreatedAt": obj.get("fileCreatedAt"),
                "fileModifiedAt": obj.get("fileModifiedAt"),
                "hasMetadata": obj.get("hasMetadata"),
                "id": obj.get("id"),
                "isArchived": obj.get("isArchived"),
                "isFavorite": obj.get("isFavorite"),
                "isOffline": obj.get("isOffline"),
                "isTrashed": obj.get("isTrashed"),
                "libraryId": obj.get("libraryId"),
                "livePhotoVideoId": obj.get("livePhotoVideoId"),
                "localDateTime": obj.get("localDateTime"),
                "originalFileName": obj.get("originalFileName"),
                "originalMimeType": obj.get("originalMimeType"),
                "originalPath": obj.get("originalPath"),
                "owner": UserResponseDto.from_dict(obj["owner"])
                if obj.get("owner") is not None
                else None,
                "ownerId": obj.get("ownerId"),
                "people": [
                    PersonWithFacesResponseDto.from_dict(_item)
                    for _item in obj["people"]
                ]
                if obj.get("people") is not None
                else None,
                "resized": obj.get("resized"),
                "stack": AssetStackResponseDto.from_dict(obj["stack"])
                if obj.get("stack") is not None
                else None,
                "tags": [TagResponseDto.from_dict(_item) for _item in obj["tags"]]
                if obj.get("tags") is not None
                else None,
                "thumbhash": obj.get("thumbhash"),
                "type": obj.get("type"),
                "unassignedFaces": [
                    AssetFaceWithoutPersonResponseDto.from_dict(_item)
                    for _item in obj["unassignedFaces"]
                ]
                if obj.get("unassignedFaces") is not None
                else None,
                "updatedAt": obj.get("updatedAt"),
                "visibility": obj.get("visibility"),
            }
        )
        return _obj
