# 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,
    StrictBool,
    StrictStr,
    field_validator,
)
from typing_extensions import Annotated, Self

from mozart_api.models.latency_profile import LatencyProfile


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

    value: Annotated[
        Optional[StrictStr],
        Field(
            description="The type of roomcompensation used / to use. simple:   For speakers without external speakers. advanced:   For products with external speakers or other advanced multichannel capabilities.   This requires that at least action in the other properties of RoomCompensationProperties is set. "
        ),
    ] = None
    action: Annotated[
        Optional[StrictStr],
        Field(
            description="Must be set if room compensation type is advanced. runAll:   Do measurements on all connected speakers. continue:   Continue from and including the speaker where last interrupted (stopped or failed). useSpeakerList:   Do measurements on the speakers in the list property. "
        ),
    ] = None
    continue_on_error: Annotated[
        Optional[StrictBool],
        Field(
            description="On failing measurement on a speaker, default behavior is to stop measurement and skip the remaining speakers. Setting continueOnError to true will make the measurement process continue and finish measurement on all speakers, even though an error ocurred on one of the speakers. ",
            alias="continueOnError",
        ),
    ] = None
    latency_profile: Annotated[
        Optional[LatencyProfile], Field(alias="latencyProfile")
    ] = None
    skip_automatic_role_assignment: Annotated[
        Optional[StrictBool],
        Field(
            description="Skip calculation of automatic role assignment.",
            alias="skipAutomaticRoleAssignment",
        ),
    ] = None
    speaker_list: Annotated[
        Optional[List[StrictStr]],
        Field(
            description="List of speaker IDs to include in room compensation / automatic role assignment measurement. Relevant e.g. if you want to create a speaker group without the external speakers included. This can not be used for doing measurements on a partial speaker group, only on all speakers in an existing group or for all speakers in a new group. ",
            alias="speakerList",
        ),
    ] = None
    speaker_preset: Annotated[
        Optional[Annotated[int, Field(le=255, strict=True, ge=0)]],
        Field(
            description="The Powerlink preset to use for the external PL/WPL speakers.",
            alias="speakerPreset",
        ),
    ] = None
    __properties: ClassVar[List[str]] = [
        "value",
        "action",
        "continueOnError",
        "latencyProfile",
        "skipAutomaticRoleAssignment",
        "speakerList",
        "speakerPreset",
    ]

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

        if value not in set(["simple", "advanced"]):
            raise ValueError("must be one of enum values ('simple', 'advanced')")
        return value

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

        if value not in set(["runAll", "continue", "useSpeakerList"]):
            raise ValueError(
                "must be one of enum values ('runAll', 'continue', 'useSpeakerList')"
            )
        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 RoomCompensationProperties 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 latency_profile
        if self.latency_profile:
            _dict["latencyProfile"] = self.latency_profile.to_dict()
        # set to None if action (nullable) is None
        # and model_fields_set contains the field
        if self.action is None and "action" in self.model_fields_set:
            _dict["action"] = None

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

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

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

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

        return _dict

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

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

        _obj = cls.model_validate({
            "value": obj.get("value"),
            "action": obj.get("action"),
            "continueOnError": obj.get("continueOnError"),
            "latencyProfile": LatencyProfile.from_dict(obj["latencyProfile"])
            if obj.get("latencyProfile") is not None
            else None,
            "skipAutomaticRoleAssignment": obj.get("skipAutomaticRoleAssignment"),
            "speakerList": obj.get("speakerList"),
            "speakerPreset": obj.get("speakerPreset"),
        })
        return _obj
