# coding: utf-8

"""
    Gigs Core API

    API to manage voice & data plans for smartphones, wearables and IoT in 200+ countries.  # noqa: E501

    The version of the OpenAPI document: 0.0.1
    Contact: support@gigs.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""


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


from typing import Any, Optional
from pydantic import BaseModel, Field, validator
from gigs_client.models.coverage import Coverage
from gigs_client.models.plan_requirements import PlanRequirements
from gigs_client.models.price import Price
from gigs_client.models.validity import Validity

class Plan(BaseModel):
    """
    Plan
    """
    object: Optional[Any] = Field(..., description="Type of object is always `plan`.")
    id: Optional[Any] = Field(..., description="Unique identifier for the plan.")
    coverage: Coverage = Field(...)
    data: Optional[Any] = Field(..., description="The data allowance included in this plan. A value of `-1` indicates unlimited data.")
    data_unit: Optional[Any] = Field(..., alias="dataUnit", description="The unit of the data value is always `byte`.")
    description: Optional[Any] = Field(..., description="The plan's description, meant to be displayable to the users.")
    image: Optional[Any] = Field(..., description="The plan's image, meant to be displayable to the users.")
    name: Optional[Any] = Field(..., description="The plan's name, meant to be displayable to the users.")
    price: Price = Field(...)
    provider: Optional[Any] = Field(..., description="The ID of the network provider supported by this plan.")
    requirements: PlanRequirements = Field(...)
    sim_types: Optional[Any] = Field(..., alias="simTypes", description="List of SIM types supported by this plan. Can be `eSIM`, `pSIM`, or both.")
    sms: Optional[Any] = Field(..., description="The SMS allowance included in this plan. A value of `-1` indicates unlimited SMS.")
    sms_unit: Optional[Any] = Field(..., alias="smsUnit", description="The unit of the sms value is always `message`.")
    status: Optional[Any] = Field(...)
    validity: Validity = Field(...)
    voice: Optional[Any] = Field(..., description="The voice call allowance in seconds included in this plan. A value of `-1` indicates unlimited voice calls.")
    voice_unit: Optional[Any] = Field(..., alias="voiceUnit", description="The unit of the voice value is always `second`.")
    created_at: Optional[Any] = Field(..., alias="createdAt", description="Time when the plan was created.")
    __properties = ["object", "id", "coverage", "data", "dataUnit", "description", "image", "name", "price", "provider", "requirements", "simTypes", "sms", "smsUnit", "status", "validity", "voice", "voiceUnit", "createdAt"]

    @validator('status')
    def status_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in ('available', 'archived', 'pending', 'draft'):
            raise ValueError("must be one of enum values ('available', 'archived', 'pending', 'draft')")
        return value

    class Config:
        """Pydantic configuration"""
        allow_population_by_field_name = True
        validate_assignment = True

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

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

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

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of coverage
        if self.coverage:
            _dict['coverage'] = self.coverage.to_dict()
        # override the default output from pydantic by calling `to_dict()` of price
        if self.price:
            _dict['price'] = self.price.to_dict()
        # override the default output from pydantic by calling `to_dict()` of requirements
        if self.requirements:
            _dict['requirements'] = self.requirements.to_dict()
        # override the default output from pydantic by calling `to_dict()` of validity
        if self.validity:
            _dict['validity'] = self.validity.to_dict()
        # set to None if object (nullable) is None
        # and __fields_set__ contains the field
        if self.object is None and "object" in self.__fields_set__:
            _dict['object'] = None

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

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

        # set to None if data_unit (nullable) is None
        # and __fields_set__ contains the field
        if self.data_unit is None and "data_unit" in self.__fields_set__:
            _dict['dataUnit'] = None

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

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

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

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

        # set to None if sim_types (nullable) is None
        # and __fields_set__ contains the field
        if self.sim_types is None and "sim_types" in self.__fields_set__:
            _dict['simTypes'] = None

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

        # set to None if sms_unit (nullable) is None
        # and __fields_set__ contains the field
        if self.sms_unit is None and "sms_unit" in self.__fields_set__:
            _dict['smsUnit'] = None

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

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

        # set to None if voice_unit (nullable) is None
        # and __fields_set__ contains the field
        if self.voice_unit is None and "voice_unit" in self.__fields_set__:
            _dict['voiceUnit'] = None

        # set to None if created_at (nullable) is None
        # and __fields_set__ contains the field
        if self.created_at is None and "created_at" in self.__fields_set__:
            _dict['createdAt'] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> Plan:
        """Create an instance of Plan from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return Plan.parse_obj(obj)

        _obj = Plan.parse_obj({
            "object": obj.get("object"),
            "id": obj.get("id"),
            "coverage": Coverage.from_dict(obj.get("coverage")) if obj.get("coverage") is not None else None,
            "data": obj.get("data"),
            "data_unit": obj.get("dataUnit"),
            "description": obj.get("description"),
            "image": obj.get("image"),
            "name": obj.get("name"),
            "price": Price.from_dict(obj.get("price")) if obj.get("price") is not None else None,
            "provider": obj.get("provider"),
            "requirements": PlanRequirements.from_dict(obj.get("requirements")) if obj.get("requirements") is not None else None,
            "sim_types": obj.get("simTypes"),
            "sms": obj.get("sms"),
            "sms_unit": obj.get("smsUnit"),
            "status": obj.get("status"),
            "validity": Validity.from_dict(obj.get("validity")) if obj.get("validity") is not None else None,
            "voice": obj.get("voice"),
            "voice_unit": obj.get("voiceUnit"),
            "created_at": obj.get("createdAt")
        })
        return _obj

