# coding: utf-8

"""
    STACKIT Network Load Balancer API

    This API offers an interface to provision and manage load balancing servers in your STACKIT project. It also has the possibility of pooling target servers for load balancing purposes.  For each load balancer provided, two VMs are deployed in your OpenStack project subject to a fee.

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

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

from __future__ import annotations

import json
import pprint
from typing import Any, ClassVar, Dict, List, Optional, Set

from pydantic import BaseModel, ConfigDict, Field, StrictBool
from typing_extensions import Self

from stackit.loadbalancer.models.loadbalancer_option_access_control import (
    LoadbalancerOptionAccessControl,
)
from stackit.loadbalancer.models.loadbalancer_option_observability import (
    LoadbalancerOptionObservability,
)


class LoadBalancerOptions(BaseModel):
    """
    Defines any optional functionality you want to have enabled on your load balancer.
    """  # noqa: E501

    access_control: Optional[LoadbalancerOptionAccessControl] = Field(default=None, alias="accessControl")
    ephemeral_address: Optional[StrictBool] = Field(default=None, alias="ephemeralAddress")
    observability: Optional[LoadbalancerOptionObservability] = None
    private_network_only: Optional[StrictBool] = Field(
        default=None,
        description="Load Balancer is accessible only via a private network ip address. Not changeable after creation.",
        alias="privateNetworkOnly",
    )
    __properties: ClassVar[List[str]] = ["accessControl", "ephemeralAddress", "observability", "privateNetworkOnly"]

    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 LoadBalancerOptions 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 access_control
        if self.access_control:
            _dict["accessControl"] = self.access_control.to_dict()
        # override the default output from pydantic by calling `to_dict()` of observability
        if self.observability:
            _dict["observability"] = self.observability.to_dict()
        return _dict

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

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

        _obj = cls.model_validate(
            {
                "accessControl": (
                    LoadbalancerOptionAccessControl.from_dict(obj["accessControl"])
                    if obj.get("accessControl") is not None
                    else None
                ),
                "ephemeralAddress": obj.get("ephemeralAddress"),
                "observability": (
                    LoadbalancerOptionObservability.from_dict(obj["observability"])
                    if obj.get("observability") is not None
                    else None
                ),
                "privateNetworkOnly": obj.get("privateNetworkOnly"),
            }
        )
        return _obj
