"""
Snowflake Managed Account API.

The Snowflake Managed Account API is a REST API that you can use to access, update, and perform certain actions on Managed Account resource in Snowflake.  # noqa: E501

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

Do not edit this file manually.
"""

from __future__ import annotations

import json
import pprint
import re

from datetime import datetime
from typing import Any, Optional

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


class ManagedAccount(BaseModel):
    """A model object representing the ManagedAccount resource.

    Constructs an object of type ManagedAccount with the provided properties.

    Parameters
    __________
    name : str
        A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
    admin_name : str
        Name of the account administrator.
    admin_password : str
        Password for the account administrator.
    account_type : str
        Type of the account.
    cloud : str, optional
        Cloud in which the managed account is located. For reader accounts, this is always the same as the cloud for the provider account — **Read-only:** *any user-provided value will be ignored.*
    region : str, optional
        Region in which the managed account is located. For reader accounts, this is always the same as the region for the provider account — **Read-only:** *any user-provided value will be ignored.*
    locator : str, optional
        Legacy identifier for the account — **Read-only:** *any user-provided value will be ignored.*
    created_on : datetime, optional
        Date and time the account was created — **Read-only:** *any user-provided value will be ignored.*
    url : str, optional
        Account URL that is used to connect to the account, in the account name format. The account identifier in this format follows the pattern <orgname>-<account_name> — **Read-only:** *any user-provided value will be ignored.*
    account_locator_url : str, optional
        Account URL that is used to connect to the account, in the legacy account locator format — **Read-only:** *any user-provided value will be ignored.*
    comment : str, optional
        Optional comment in which to store information related to the account.
    """

    name: Annotated[str, Field(strict=True)]

    cloud: Optional[StrictStr] = None

    region: Optional[StrictStr] = None

    locator: Optional[StrictStr] = None

    created_on: Optional[datetime] = None

    url: Optional[StrictStr] = None

    account_locator_url: Optional[StrictStr] = None

    comment: Optional[StrictStr] = None

    admin_name: Optional[StrictStr]

    admin_password: Optional[SecretStr]

    account_type: StrictStr

    __properties = [
        "name",
        "cloud",
        "region",
        "locator",
        "created_on",
        "url",
        "account_locator_url",
        "comment",
        "admin_name",
        "admin_password",
        "account_type",
    ]

    @field_validator("name")
    def name_validate_regular_expression(cls, v):
        if not re.match(r"""^\"([^\"]|\"\")+\"|[a-zA-Z_][a-zA-Z0-9_$]*$""", v):
            raise ValueError(r"""must validate the regular expression /^"([^"]|"")+"|[a-zA-Z_][a-zA-Z0-9_$]*$/""")
        return v

    @field_validator("account_type")
    def account_type_validate_enum(cls, v):
        if v not in ("READER"):
            raise ValueError("must validate the enum values ('READER')")
        return v

    model_config = ConfigDict(
        validate_by_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) -> ManagedAccount:
        """Create an instance of ManagedAccount from a JSON string."""
        return cls.from_dict(json.loads(json_str))

    def to_dict(
        self,
        hide_readonly_properties: bool = False,
    ) -> dict[str, Any]:
        """Returns the dictionary representation of the model using alias."""
        exclude_properties = set()

        if hide_readonly_properties:
            exclude_properties.update(
                {
                    "cloud",
                    "region",
                    "locator",
                    "created_on",
                    "url",
                    "account_locator_url",
                }
            )

        _dict = self.model_dump(serialize_as_any=True, by_alias=True, exclude=exclude_properties, exclude_none=True)

        # set to None if admin_name (nullable) is None
        if self.admin_name is None:
            _dict["admin_name"] = None

        # set to None if admin_password (nullable) is None
        if self.admin_password is None:
            _dict["admin_password"] = None

        return _dict

    def to_dict_without_readonly_properties(self) -> dict[str, Any]:
        """Return the dictionary representation of the model without readonly properties."""
        return self.to_dict(hide_readonly_properties=True)

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

        if type(obj) is not dict:
            return ManagedAccount.model_validate(obj)

        _obj = ManagedAccount.model_validate(
            {
                "name": obj.get("name"),
                "cloud": obj.get("cloud"),
                "region": obj.get("region"),
                "locator": obj.get("locator"),
                "created_on": obj.get("created_on"),
                "url": obj.get("url"),
                "account_locator_url": obj.get("account_locator_url"),
                "comment": obj.get("comment"),
                "admin_name": obj.get("admin_name"),
                "admin_password": obj.get("admin_password"),
                "account_type": obj.get("account_type") if obj.get("account_type") is not None else "READER",
            }
        )

        return _obj


class ManagedAccountModel:
    def __init__(
        self,
        name: str,
        admin_name: str,
        admin_password: str,
        account_type: str = "READER",
        # optional properties
        cloud: Optional[str] = None,
        region: Optional[str] = None,
        locator: Optional[str] = None,
        created_on: Optional[datetime] = None,
        url: Optional[str] = None,
        account_locator_url: Optional[str] = None,
        comment: Optional[str] = None,
    ):
        """A model object representing the ManagedAccount resource.

        Constructs an object of type ManagedAccount with the provided properties.

        Parameters
        __________
        name : str
            A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
        admin_name : str
            Name of the account administrator.
        admin_password : str
            Password for the account administrator.
        account_type : str
            Type of the account.
        cloud : str, optional
            Cloud in which the managed account is located. For reader accounts, this is always the same as the cloud for the provider account.
        region : str, optional
            Region in which the managed account is located. For reader accounts, this is always the same as the region for the provider account.
        locator : str, optional
            Legacy identifier for the account.
        created_on : datetime, optional
            Date and time the account was created.
        url : str, optional
            Account URL that is used to connect to the account, in the account name format. The account identifier in this format follows the pattern <orgname>-<account_name>.
        account_locator_url : str, optional
            Account URL that is used to connect to the account, in the legacy account locator format.
        comment : str, optional
            Optional comment in which to store information related to the account.
        """
        self.name = name
        self.cloud = cloud
        self.region = region
        self.locator = locator
        self.created_on = created_on
        self.url = url
        self.account_locator_url = account_locator_url
        self.comment = comment
        self.admin_name = admin_name
        self.admin_password = admin_password
        self.account_type = account_type

    __properties = [
        "name",
        "cloud",
        "region",
        "locator",
        "created_on",
        "url",
        "account_locator_url",
        "comment",
        "admin_name",
        "admin_password",
        "account_type",
    ]

    def __repr__(self) -> str:
        return repr(self._to_model())

    def _to_model(self):
        return ManagedAccount(
            name=self.name,
            cloud=self.cloud,
            region=self.region,
            locator=self.locator,
            created_on=self.created_on,
            url=self.url,
            account_locator_url=self.account_locator_url,
            comment=self.comment,
            admin_name=self.admin_name,
            admin_password=self.admin_password,
            account_type=self.account_type,
        )

    @classmethod
    def _from_model(cls, model) -> ManagedAccountModel:
        return ManagedAccountModel(
            name=model.name,
            cloud=model.cloud,
            region=model.region,
            locator=model.locator,
            created_on=model.created_on,
            url=model.url,
            account_locator_url=model.account_locator_url,
            comment=model.comment,
            admin_name=model.admin_name,
            admin_password=model.admin_password,
            account_type=model.account_type,
        )

    def to_dict(self):
        """Create a dictionary of the properties from a ManagedAccount.

        This method constructs a dictionary with the key-value entries corresponding to the properties of the ManagedAccount object.

        Returns
        _______
        dict
            A dictionary object created using the input model.
        """
        return self._to_model().to_dict()

    @classmethod
    def from_dict(cls, obj: dict) -> ManagedAccountModel:
        """Create an instance of ManagedAccount from a dict.

        This method constructs a ManagedAccount object from a dictionary with the key-value pairs of its properties.

        Parameters
        ----------
        obj : dict
            A dictionary whose keys and values correspond to the properties of the resource object.

        Returns
        _______
        ManagedAccount
            A ManagedAccount object created using the input dictionary; this will fail if the required properties are missing.
        """
        return cls._from_model(ManagedAccount.from_dict(obj))


ManagedAccount._model_class = ManagedAccountModel
