# coding: utf-8

"""
    Carrier API

    **Seaplane Global Messaging Service**  For information about authentication see [authentication](/docs/authentication)   # noqa: E501

    The version of the OpenAPI document: 1.1.0-beta
    Contact: support@seaplane.io
    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 Optional
from pydantic import BaseModel, Field, StrictBool, StrictStr, conint, constr, validator


class CarrierInputConfig(BaseModel):
    """
    Configuration for Carrier stream input
    """

    stream: Optional[constr(strict=True, max_length=64, min_length=1)] = Field(
        None, description="stream (mutually exclusive with subject)"
    )
    subject: Optional[constr(strict=True)] = Field(
        None,
        description="Space-delimited list of subjects to subscribe to (mutually exclusive with stream). Note that multiple subjects are only allowed when attached to existing pull consumers. ",
    )
    queue: Optional[StrictStr] = Field(None, description="Queue group (optional)")
    durable: Optional[constr(strict=True)] = Field(
        None, description="Durable consumer name (optional)"
    )
    bind: Optional[StrictBool] = Field(None, description="Bind to an existing consumer")
    deliver: Optional[StrictStr] = Field(
        "all",
        description="Start consuming with a durable consumer. This cannot be updated once a consumer is created",
    )
    ack_wait: Optional[constr(strict=True)] = Field(
        "30s",
        description="The maximum amount of time NATS server should wait for an ack from consumer",
    )
    max_ack_pending: Optional[conint(strict=True, le=100000, ge=1)] = Field(
        1024, description="Allowed in-flight messages before halting"
    )
    __properties = [
        "stream",
        "subject",
        "queue",
        "durable",
        "bind",
        "deliver",
        "ack_wait",
        "max_ack_pending",
    ]

    @validator("stream")
    def stream_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^[a-zA-Z0-9-_]+$", value):
            raise ValueError(r"must validate the regular expression /^[a-zA-Z0-9-_]+$/")
        return value

    @validator("subject")
    def subject_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(
            r"^([a-zA-Z0-9-_]{1,64}(.[a-zA-Z0-9-_*]{1,64})*(.>)?)([ ]([a-zA-Z0-9-_]{1,64}(.[a-zA-Z0-9-_*]{1,64})*(.>)?))*$",
            value,
        ):
            raise ValueError(
                r"must validate the regular expression /^([a-zA-Z0-9-_]{1,64}(.[a-zA-Z0-9-_*]{1,64})*(.>)?)([ ]([a-zA-Z0-9-_]{1,64}(.[a-zA-Z0-9-_*]{1,64})*(.>)?))*$/"
            )
        return value

    @validator("durable")
    def durable_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^[a-zA-Z0-9-_]{1,32}$", value):
            raise ValueError(
                r"must validate the regular expression /^[a-zA-Z0-9-_]{1,32}$/"
            )
        return value

    @validator("deliver")
    def deliver_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in ("all", "last", "new"):
            raise ValueError("must be one of enum values ('all', 'last', 'new')")
        return value

    @validator("ack_wait")
    def ack_wait_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^([0-9]{1,6}h|[0-9]{1,7}m|[0-9]{1,9}s)$", value):
            raise ValueError(
                r"must validate the regular expression /^([0-9]{1,6}h|[0-9]{1,7}m|[0-9]{1,9}s)$/"
            )
        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) -> CarrierInputConfig:
        """Create an instance of CarrierInputConfig 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)
        return _dict

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

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

        _obj = CarrierInputConfig.parse_obj(
            {
                "stream": obj.get("stream"),
                "subject": obj.get("subject"),
                "queue": obj.get("queue"),
                "durable": obj.get("durable"),
                "bind": obj.get("bind"),
                "deliver": obj.get("deliver")
                if obj.get("deliver") is not None
                else "all",
                "ack_wait": obj.get("ack_wait")
                if obj.get("ack_wait") is not None
                else "30s",
                "max_ack_pending": obj.get("max_ack_pending")
                if obj.get("max_ack_pending") is not None
                else 1024,
            }
        )
        return _obj
