# coding: utf-8

"""
    Metal API

    The version of the OpenAPI document: 1.0.0
    Contact: support@equinixmetal.com
    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, StrictBool, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from equinix.services.metalv1.models.metadata_network import MetadataNetwork
from typing import Optional, Set
from typing_extensions import Self

class Metadata(BaseModel):
    """
    Metadata
    """ # noqa: E501
    var_class: Optional[StrictStr] = Field(default=None, alias="class")
    customdata: Optional[Dict[str, Any]] = None
    facility: Optional[StrictStr] = Field(default=None, description="The facility code of the instance")
    hostname: Optional[StrictStr] = None
    href: Optional[StrictStr] = None
    id: Optional[StrictStr] = None
    iqn: Optional[StrictStr] = None
    metro: Optional[StrictStr] = Field(default=None, description="The metro code of the instance")
    network: Optional[MetadataNetwork] = None
    operating_system: Optional[Dict[str, Any]] = None
    plan: Optional[StrictStr] = Field(default=None, description="The plan slug of the instance")
    private_subnets: Optional[List[StrictStr]] = Field(default=None, description="An array of the private subnets")
    reserved: Optional[StrictBool] = None
    specs: Optional[Dict[str, Any]] = Field(default=None, description="The specs of the plan version of the instance")
    ssh_keys: Optional[List[StrictStr]] = None
    state: Optional[StrictStr] = Field(default=None, description="The current state the instance is in.  * When an instance is initially created it will be in the `queued` state until it is picked up by the provisioner. * Once provisioning has begun on the instance it's state will move to `provisioning`. * When an instance is deleted, it will move to `deprovisioning` state until the deprovision is completed and the instance state moves to `deleted`. * If an instance fails to provision or deprovision it will move to `failed` state. * Once an instance has completed provisioning it will move to `active` state. * If an instance is currently powering off or powering on it will move to `powering_off` or `powering_on` states respectively.  * When the instance is powered off completely it will move to the `inactive` state. * When an instance is powered on completely it will move to the `active` state. * Using the reinstall action to install a new OS on the instance will cause the instance state to change to `reinstalling`. * When the reinstall action is complete the instance will move to `active` state.")
    switch_short_id: Optional[StrictStr] = None
    tags: Optional[List[StrictStr]] = None
    volumes: Optional[List[StrictStr]] = None
    __properties: ClassVar[List[str]] = ["class", "customdata", "facility", "hostname", "href", "id", "iqn", "metro", "network", "operating_system", "plan", "private_subnets", "reserved", "specs", "ssh_keys", "state", "switch_short_id", "tags", "volumes"]

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

        if value not in set(['queued', 'provisioning', 'deprovisioning', 'reinstalling', 'active', 'inactive', 'failed', 'powering_on', 'powering_off', 'deleted']):
            raise ValueError("must be one of enum values ('queued', 'provisioning', 'deprovisioning', 'reinstalling', 'active', 'inactive', 'failed', 'powering_on', 'powering_off', 'deleted')")
        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 Metadata 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 network
        if self.network:
            _dict['network'] = self.network.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "class": obj.get("class"),
            "customdata": obj.get("customdata"),
            "facility": obj.get("facility"),
            "hostname": obj.get("hostname"),
            "href": obj.get("href"),
            "id": obj.get("id"),
            "iqn": obj.get("iqn"),
            "metro": obj.get("metro"),
            "network": MetadataNetwork.from_dict(obj["network"]) if obj.get("network") is not None else None,
            "operating_system": obj.get("operating_system"),
            "plan": obj.get("plan"),
            "private_subnets": obj.get("private_subnets"),
            "reserved": obj.get("reserved"),
            "specs": obj.get("specs"),
            "ssh_keys": obj.get("ssh_keys"),
            "state": obj.get("state"),
            "switch_short_id": obj.get("switch_short_id"),
            "tags": obj.get("tags"),
            "volumes": obj.get("volumes")
        })
        return _obj


