# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.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 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
from mixpeek.models.template_mode import TemplateMode
from mixpeek.models.template_scope import TemplateScope
from mixpeek.models.template_type import TemplateType
from typing import Optional, Set
from typing_extensions import Self

class BaseTemplateModel(BaseModel):
    """
    Base template model with common fields for all template types.  This model is stored in MongoDB and supports three template scopes: - System: Mixpeek defaults (all orgs) - Organization: All users in the org - User: Only the creator
    """ # noqa: E501
    template_id: Annotated[str, Field(strict=True)] = Field(description="Unique template identifier (e.g., 'tmpl_semantic_search')")
    template_type: TemplateType = Field(description="Type of resource this template creates")
    mode: Optional[TemplateMode] = Field(default=None, description="Template instantiation mode: clone (with data), config (empty), or scaffold (preset)")
    scope: TemplateScope = Field(description="Template scope (system or organization)")
    internal_id: StrictStr = Field(description="Organization internal ID. For system templates, use 'system'. For org templates, use the actual internal_id.")
    name: Annotated[str, Field(min_length=1, strict=True, max_length=100)] = Field(description="Human-readable template name")
    description: Annotated[str, Field(min_length=1, strict=True, max_length=1000)] = Field(description="Detailed description of the template's purpose")
    category: Optional[StrictStr] = Field(default=None, description="Optional category for organizing templates")
    configuration: Dict[str, Any] = Field(description="Template-specific configuration (varies by template_type)")
    tags: Optional[List[StrictStr]] = Field(default=None, description="Tags for categorizing and filtering templates")
    is_active: Optional[StrictBool] = Field(default=True, description="Whether this template is available for use")
    is_public: Optional[StrictBool] = Field(default=False, description="Whether this template is publicly discoverable without authentication")
    use_cases: Optional[List[StrictStr]] = Field(default=None, description="List of common use cases for this template")
    requirements: Optional[List[StrictStr]] = Field(default=None, description="List of requirements (e.g., 'Requires text embeddings')")
    created_by: Optional[StrictStr] = Field(default=None, description="User ID who created this template (for org templates)")
    source_resource_id: Optional[StrictStr] = Field(default=None, description="ID of the resource this template was created from (for org templates)")
    created_at: Optional[datetime] = Field(default=None, description="Timestamp when template was created")
    updated_at: Optional[datetime] = Field(default=None, description="Timestamp when template was last updated")
    __properties: ClassVar[List[str]] = ["template_id", "template_type", "mode", "scope", "internal_id", "name", "description", "category", "configuration", "tags", "is_active", "is_public", "use_cases", "requirements", "created_by", "source_resource_id", "created_at", "updated_at"]

    @field_validator('template_id')
    def template_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if not re.match(r"^tmpl_[a-z0-9_]+$", value):
            raise ValueError(r"must validate the regular expression /^tmpl_[a-z0-9_]+$/")
        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 BaseTemplateModel 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,
        )
        return _dict

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

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

        _obj = cls.model_validate({
            "template_id": obj.get("template_id"),
            "template_type": obj.get("template_type"),
            "mode": obj.get("mode"),
            "scope": obj.get("scope"),
            "internal_id": obj.get("internal_id"),
            "name": obj.get("name"),
            "description": obj.get("description"),
            "category": obj.get("category"),
            "configuration": obj.get("configuration"),
            "tags": obj.get("tags"),
            "is_active": obj.get("is_active") if obj.get("is_active") is not None else True,
            "is_public": obj.get("is_public") if obj.get("is_public") is not None else False,
            "use_cases": obj.get("use_cases"),
            "requirements": obj.get("requirements"),
            "created_by": obj.get("created_by"),
            "source_resource_id": obj.get("source_resource_id"),
            "created_at": obj.get("created_at"),
            "updated_at": obj.get("updated_at")
        })
        return _obj


