# coding: utf-8

"""
    YouTube Data API v3

    The YouTube Data API v3 is an API that provides access to YouTube data, such as videos, playlists, and channels.

    The version of the OpenAPI document: v3
    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 pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from youtube_ti.models.video_age_gating import VideoAgeGating
from youtube_ti.models.video_content_details import VideoContentDetails
from youtube_ti.models.video_file_details import VideoFileDetails
from youtube_ti.models.video_live_streaming_details import VideoLiveStreamingDetails
from youtube_ti.models.video_monetization_details import VideoMonetizationDetails
from youtube_ti.models.video_paid_product_placement_details import VideoPaidProductPlacementDetails
from youtube_ti.models.video_player import VideoPlayer
from youtube_ti.models.video_processing_details import VideoProcessingDetails
from youtube_ti.models.video_recording_details import VideoRecordingDetails
from youtube_ti.models.video_snippet import VideoSnippet
from youtube_ti.models.video_statistics import VideoStatistics
from youtube_ti.models.video_status import VideoStatus
from youtube_ti.models.video_suggestions import VideoSuggestions
from youtube_ti.models.video_topic_details import VideoTopicDetails
from typing import Optional, Set
from typing_extensions import Self

class Video(BaseModel):
    """
    A *video* resource represents a YouTube video.
    """ # noqa: E501
    age_gating: Optional[VideoAgeGating] = Field(default=None, alias="ageGating")
    content_details: Optional[VideoContentDetails] = Field(default=None, alias="contentDetails")
    etag: Optional[StrictStr] = Field(default=None, description="Etag of this resource.")
    file_details: Optional[VideoFileDetails] = Field(default=None, alias="fileDetails")
    id: Optional[StrictStr] = Field(default=None, description="The ID that YouTube uses to uniquely identify the video.")
    kind: Optional[StrictStr] = Field(default='youtube#video', description="Identifies what kind of resource this is. Value: the fixed string \"youtube#video\".")
    live_streaming_details: Optional[VideoLiveStreamingDetails] = Field(default=None, alias="liveStreamingDetails")
    localizations: Optional[Dict[str, Any]] = Field(default=None, description="The localizations object contains localized versions of the basic details about the video, such as its title and description.")
    monetization_details: Optional[VideoMonetizationDetails] = Field(default=None, alias="monetizationDetails")
    paid_product_placement_details: Optional[VideoPaidProductPlacementDetails] = Field(default=None, alias="paidProductPlacementDetails")
    player: Optional[VideoPlayer] = None
    processing_details: Optional[VideoProcessingDetails] = Field(default=None, alias="processingDetails")
    project_details: Optional[Dict[str, Any]] = Field(default=None, description="DEPRECATED. b/157517979: This part was never populated after it was added. However, it sees non-zero traffic because there is generated client code in the wild that refers to it [1]. We keep this field and do NOT remove it because otherwise V3 would return an error when this part gets requested [2]. [1] https://developers.google.com/resources/api-libraries/documentation/youtube/v3/csharp/latest/classGoogle_1_1Apis_1_1YouTube_1_1v3_1_1Data_1_1VideoProjectDetails.html [2] http://google3/video/youtube/src/python/servers/data_api/common.py?l=1565-1569&rcl=344141677", alias="projectDetails")
    recording_details: Optional[VideoRecordingDetails] = Field(default=None, alias="recordingDetails")
    snippet: Optional[VideoSnippet] = None
    statistics: Optional[VideoStatistics] = None
    status: Optional[VideoStatus] = None
    suggestions: Optional[VideoSuggestions] = None
    topic_details: Optional[VideoTopicDetails] = Field(default=None, alias="topicDetails")
    __properties: ClassVar[List[str]] = ["ageGating", "contentDetails", "etag", "fileDetails", "id", "kind", "liveStreamingDetails", "localizations", "monetizationDetails", "paidProductPlacementDetails", "player", "processingDetails", "projectDetails", "recordingDetails", "snippet", "statistics", "status", "suggestions", "topicDetails"]

    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 Video 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 age_gating
        if self.age_gating:
            _dict['ageGating'] = self.age_gating.to_dict()
        # override the default output from pydantic by calling `to_dict()` of content_details
        if self.content_details:
            _dict['contentDetails'] = self.content_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of file_details
        if self.file_details:
            _dict['fileDetails'] = self.file_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of live_streaming_details
        if self.live_streaming_details:
            _dict['liveStreamingDetails'] = self.live_streaming_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of monetization_details
        if self.monetization_details:
            _dict['monetizationDetails'] = self.monetization_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of paid_product_placement_details
        if self.paid_product_placement_details:
            _dict['paidProductPlacementDetails'] = self.paid_product_placement_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of player
        if self.player:
            _dict['player'] = self.player.to_dict()
        # override the default output from pydantic by calling `to_dict()` of processing_details
        if self.processing_details:
            _dict['processingDetails'] = self.processing_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of recording_details
        if self.recording_details:
            _dict['recordingDetails'] = self.recording_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of snippet
        if self.snippet:
            _dict['snippet'] = self.snippet.to_dict()
        # override the default output from pydantic by calling `to_dict()` of statistics
        if self.statistics:
            _dict['statistics'] = self.statistics.to_dict()
        # override the default output from pydantic by calling `to_dict()` of status
        if self.status:
            _dict['status'] = self.status.to_dict()
        # override the default output from pydantic by calling `to_dict()` of suggestions
        if self.suggestions:
            _dict['suggestions'] = self.suggestions.to_dict()
        # override the default output from pydantic by calling `to_dict()` of topic_details
        if self.topic_details:
            _dict['topicDetails'] = self.topic_details.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "ageGating": VideoAgeGating.from_dict(obj["ageGating"]) if obj.get("ageGating") is not None else None,
            "contentDetails": VideoContentDetails.from_dict(obj["contentDetails"]) if obj.get("contentDetails") is not None else None,
            "etag": obj.get("etag"),
            "fileDetails": VideoFileDetails.from_dict(obj["fileDetails"]) if obj.get("fileDetails") is not None else None,
            "id": obj.get("id"),
            "kind": obj.get("kind") if obj.get("kind") is not None else 'youtube#video',
            "liveStreamingDetails": VideoLiveStreamingDetails.from_dict(obj["liveStreamingDetails"]) if obj.get("liveStreamingDetails") is not None else None,
            "localizations": obj.get("localizations"),
            "monetizationDetails": VideoMonetizationDetails.from_dict(obj["monetizationDetails"]) if obj.get("monetizationDetails") is not None else None,
            "paidProductPlacementDetails": VideoPaidProductPlacementDetails.from_dict(obj["paidProductPlacementDetails"]) if obj.get("paidProductPlacementDetails") is not None else None,
            "player": VideoPlayer.from_dict(obj["player"]) if obj.get("player") is not None else None,
            "processingDetails": VideoProcessingDetails.from_dict(obj["processingDetails"]) if obj.get("processingDetails") is not None else None,
            "projectDetails": obj.get("projectDetails"),
            "recordingDetails": VideoRecordingDetails.from_dict(obj["recordingDetails"]) if obj.get("recordingDetails") is not None else None,
            "snippet": VideoSnippet.from_dict(obj["snippet"]) if obj.get("snippet") is not None else None,
            "statistics": VideoStatistics.from_dict(obj["statistics"]) if obj.get("statistics") is not None else None,
            "status": VideoStatus.from_dict(obj["status"]) if obj.get("status") is not None else None,
            "suggestions": VideoSuggestions.from_dict(obj["suggestions"]) if obj.get("suggestions") is not None else None,
            "topicDetails": VideoTopicDetails.from_dict(obj["topicDetails"]) if obj.get("topicDetails") is not None else None
        })
        return _obj


