# coding: utf-8
"""
    Snowflake Stage API

    The Snowflake Stage API is a REST API that you can use to access, update, and perform certain actions on stage resources in a Snowflake database.  # 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 pprint
import re  # noqa: F401
import json

from typing import Union

from snowflake.core.stage._generated.models.credentials import Credentials

from snowflake.core.stage._generated.models.stage_directory_table import StageDirectoryTable

from snowflake.core.stage._generated.models.stage_encryption import StageEncryption

from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator

from typing import Any, ClassVar, Dict, List, Optional

from typing_extensions import Annotated


class Stage(BaseModel):

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

    kind: Optional[StrictStr] = 'PERMANENT'

    url: Optional[StrictStr] = None

    endpoint: Optional[StrictStr] = None

    storage_integration: Optional[Annotated[str, Field(strict=True)]] = None

    comment: Optional[StrictStr] = None

    credentials: Optional[Credentials] = None

    encryption: Optional[StageEncryption] = None

    directory_table: Optional[StageDirectoryTable] = None

    created_on: Optional[datetime] = None

    has_credentials: Optional[StrictBool] = None

    has_encryption_key: Optional[StrictBool] = None

    owner: Optional[StrictStr] = None

    owner_role_type: Optional[StrictStr] = None

    region: Optional[StrictStr] = None

    cloud: Optional[StrictStr] = None

    __properties = [
        "name", "kind", "url", "endpoint", "storage_integration", "comment",
        "credentials", "encryption", "directory_table", "created_on",
        "has_credentials", "has_encryption_key", "owner", "owner_role_type",
        "region", "cloud"
    ]

    @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('kind')
    def kind_validate_enum(cls, v):

        if v is None:
            return v
        if v not in ('PERMANENT', 'TEMPORARY'):
            raise ValueError("must validate the enum values ()")
        return v

    @field_validator('storage_integration')
    def storage_integration_validate_regular_expression(cls, v):

        if v is None:
            return 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

    class Config:
        populate_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) -> Stage:
        """Create an instance of Stage 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 = dict(
            self._iter(to_dict=True,
                       by_alias=True,
                       exclude={
                           "created_on",
                           "has_credentials",
                           "has_encryption_key",
                           "owner",
                           "owner_role_type",
                           "region",
                           "cloud",
                       },
                       exclude_none=True))

        # override the default output from pydantic by calling `to_dict()` of credentials
        if self.credentials:
            _dict['credentials'] = self.credentials.to_dict()

        # override the default output from pydantic by calling `to_dict()` of encryption
        if self.encryption:
            _dict['encryption'] = self.encryption.to_dict()

        # override the default output from pydantic by calling `to_dict()` of directory_table
        if self.directory_table:
            _dict['directory_table'] = self.directory_table.to_dict()

        return _dict

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

        if obj is None:
            return None

        if type(obj) is not dict:
            return Stage.parse_obj(obj)

        _obj = Stage.parse_obj({
            "name":
            obj.get("name"),
            "kind":
            obj.get("kind") if obj.get("kind") is not None else 'PERMANENT',
            "url":
            obj.get("url"),
            "endpoint":
            obj.get("endpoint"),
            "storage_integration":
            obj.get("storage_integration"),
            "comment":
            obj.get("comment"),
            "credentials":
            Credentials.from_dict(obj.get("credentials"))
            if obj.get("credentials") is not None else None,
            "encryption":
            StageEncryption.from_dict(obj.get("encryption"))
            if obj.get("encryption") is not None else None,
            "directory_table":
            StageDirectoryTable.from_dict(obj.get("directory_table"))
            if obj.get("directory_table") is not None else None,
            "created_on":
            obj.get("created_on"),
            "has_credentials":
            obj.get("has_credentials"),
            "has_encryption_key":
            obj.get("has_encryption_key"),
            "owner":
            obj.get("owner"),
            "owner_role_type":
            obj.get("owner_role_type"),
            "region":
            obj.get("region"),
            "cloud":
            obj.get("cloud"),
        })

        return _obj


from typing import Optional, List, Dict

from snowflake.core.stage._generated.models.credentials import Credentials

from snowflake.core.stage._generated.models.stage_directory_table import StageDirectoryTable

from snowflake.core.stage._generated.models.stage_encryption import StageEncryption


class StageModel():

    def __init__(
        self,
        name: str,
        # optional properties
        kind: Optional[str] = 'PERMANENT',
        url: Optional[str] = None,
        endpoint: Optional[str] = None,
        storage_integration: Optional[str] = None,
        comment: Optional[str] = None,
        credentials: Optional[Credentials] = None,
        encryption: Optional[StageEncryption] = None,
        directory_table: Optional[StageDirectoryTable] = None,
        created_on: Optional[datetime] = None,
        has_credentials: Optional[bool] = None,
        has_encryption_key: Optional[bool] = None,
        owner: Optional[str] = None,
        owner_role_type: Optional[str] = None,
        region: Optional[str] = None,
        cloud: Optional[str] = None,
    ):

        self.name = name
        self.kind = kind
        self.url = url
        self.endpoint = endpoint
        self.storage_integration = storage_integration
        self.comment = comment
        self.credentials = credentials
        self.encryption = encryption
        self.directory_table = directory_table
        self.created_on = created_on
        self.has_credentials = has_credentials
        self.has_encryption_key = has_encryption_key
        self.owner = owner
        self.owner_role_type = owner_role_type
        self.region = region
        self.cloud = cloud

    __properties = [
        "name", "kind", "url", "endpoint", "storage_integration", "comment",
        "credentials", "encryption", "directory_table", "created_on",
        "has_credentials", "has_encryption_key", "owner", "owner_role_type",
        "region", "cloud"
    ]

    def _to_model(self):
        return Stage(
            name=self.name,
            kind=self.kind,
            url=self.url,
            endpoint=self.endpoint,
            storage_integration=self.storage_integration,
            comment=self.comment,
            credentials=self.credentials._to_model()
            if self.credentials is not None else None,
            encryption=self.encryption._to_model()
            if self.encryption is not None else None,
            directory_table=self.directory_table._to_model()
            if self.directory_table is not None else None,
            created_on=self.created_on,
            has_credentials=self.has_credentials,
            has_encryption_key=self.has_encryption_key,
            owner=self.owner,
            owner_role_type=self.owner_role_type,
            region=self.region,
            cloud=self.cloud,
        )

    @classmethod
    def _from_model(cls, model) -> StageModel:
        return StageModel(
            name=model.name,
            kind=model.kind,
            url=model.url,
            endpoint=model.endpoint,
            storage_integration=model.storage_integration,
            comment=model.comment,
            credentials=CredentialsModel._from_model(model.credentials)
            if model.credentials is not None else None,
            encryption=StageEncryptionModel._from_model(model.encryption)
            if model.encryption is not None else None,
            directory_table=StageDirectoryTableModel._from_model(
                model.directory_table)
            if model.directory_table is not None else None,
            created_on=model.created_on,
            has_credentials=model.has_credentials,
            has_encryption_key=model.has_encryption_key,
            owner=model.owner,
            owner_role_type=model.owner_role_type,
            region=model.region,
            cloud=model.cloud,
        )

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        return self._to_model().to_dict()

    @classmethod
    def from_dict(cls, obj: dict) -> StageModel:
        """Create an instance of Stage from a dict"""
        return cls._from_model(Stage.from_dict(obj))


Stage._model_class = StageModel
