# coding: utf-8

"""
Mozart platform API

API for interacting with the Mozart platform.

The version of the OpenAPI document: 0.2.0
Contact: support@bang-olufsen.dk
Generated by OpenAPI Generator (https://openapi-generator.tech)

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

from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set

from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
from typing_extensions import Annotated, Self

from mozart_api.models.microphones_state import MicrophonesState
from mozart_api.models.playback_state import PlaybackState
from mozart_api.models.power_state_enum import PowerStateEnum
from mozart_api.models.software_update_state import SoftwareUpdateState
from mozart_api.models.sound_settings import SoundSettings
from mozart_api.models.source import Source
from mozart_api.models.tv_state import TvState
from mozart_api.models.volume_state import VolumeState


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

    microphones: Optional[MicrophonesState] = None
    playback: Optional[PlaybackState] = None
    power_state: Annotated[Optional[PowerStateEnum], Field(alias="powerState")] = None
    software_update_state: Annotated[
        Optional[SoftwareUpdateState], Field(alias="softwareUpdateState")
    ] = None
    sound_settings: Annotated[Optional[SoundSettings], Field(alias="soundSettings")] = (
        None
    )
    source: Optional[Source] = None
    system_state: Annotated[Optional[StrictStr], Field(alias="systemState")] = None
    tv: Optional[TvState] = None
    volume: Optional[VolumeState] = None
    __properties: ClassVar[List[str]] = [
        "microphones",
        "playback",
        "powerState",
        "softwareUpdateState",
        "soundSettings",
        "source",
        "systemState",
        "tv",
        "volume",
    ]

    @field_validator("system_state")
    def system_state_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set([
            "error",
            "booted",
            "firmwareUpdate",
            "idle",
            "initializing",
            "playback",
            "roomCompensation",
            "selfDiagnostics",
            "shuttingDown",
        ]):
            raise ValueError(
                "must be one of enum values ('error', 'booted', 'firmwareUpdate', 'idle', 'initializing', 'playback', 'roomCompensation', 'selfDiagnostics', 'shuttingDown')"
            )
        return value

    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 ProductState 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 microphones
        if self.microphones:
            _dict["microphones"] = self.microphones.to_dict()
        # override the default output from pydantic by calling `to_dict()` of playback
        if self.playback:
            _dict["playback"] = self.playback.to_dict()
        # override the default output from pydantic by calling `to_dict()` of power_state
        if self.power_state:
            _dict["powerState"] = self.power_state.to_dict()
        # override the default output from pydantic by calling `to_dict()` of software_update_state
        if self.software_update_state:
            _dict["softwareUpdateState"] = self.software_update_state.to_dict()
        # override the default output from pydantic by calling `to_dict()` of sound_settings
        if self.sound_settings:
            _dict["soundSettings"] = self.sound_settings.to_dict()
        # override the default output from pydantic by calling `to_dict()` of source
        if self.source:
            _dict["source"] = self.source.to_dict()
        # override the default output from pydantic by calling `to_dict()` of tv
        if self.tv:
            _dict["tv"] = self.tv.to_dict()
        # override the default output from pydantic by calling `to_dict()` of volume
        if self.volume:
            _dict["volume"] = self.volume.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "microphones": MicrophonesState.from_dict(obj["microphones"])
            if obj.get("microphones") is not None
            else None,
            "playback": PlaybackState.from_dict(obj["playback"])
            if obj.get("playback") is not None
            else None,
            "powerState": PowerStateEnum.from_dict(obj["powerState"])
            if obj.get("powerState") is not None
            else None,
            "softwareUpdateState": SoftwareUpdateState.from_dict(
                obj["softwareUpdateState"]
            )
            if obj.get("softwareUpdateState") is not None
            else None,
            "soundSettings": SoundSettings.from_dict(obj["soundSettings"])
            if obj.get("soundSettings") is not None
            else None,
            "source": Source.from_dict(obj["source"])
            if obj.get("source") is not None
            else None,
            "systemState": obj.get("systemState"),
            "tv": TvState.from_dict(obj["tv"]) if obj.get("tv") is not None else None,
            "volume": VolumeState.from_dict(obj["volume"])
            if obj.get("volume") is not None
            else None,
        })
        return _obj
