# coding: utf-8

"""
    ibl-data-manager

    API for iblai

    The version of the OpenAPI document: 4.202.1-ai-plus
    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, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from uuid import UUID
from iblai.models.call_configuration import CallConfiguration
from iblai.models.greeting_method_enum import GreetingMethodEnum
from iblai.models.mcp_server import MCPServer
from iblai.models.mentor_category import MentorCategory
from iblai.models.mentor_type import MentorType
from iblai.models.starter_prompts_b04_enum import StarterPromptsB04Enum
from iblai.models.subject import Subject
from typing import Optional, Set
from typing_extensions import Self

class Mentor(BaseModel):
    """
    Mentor
    """ # noqa: E501
    id: StrictInt
    name: Annotated[str, Field(strict=True, max_length=255)]
    unique_id: Optional[UUID] = None
    flow: Optional[Any] = Field(default=None, description="The langflow json for the mentor")
    slug: Optional[Annotated[str, Field(strict=True, max_length=255)]] = None
    platform: Optional[Annotated[str, Field(strict=True, max_length=255)]] = None
    allow_anonymous: Optional[StrictBool] = None
    enable_offline_mode: Optional[StrictBool] = Field(default=None, description="Allow this mentor to be used offline with local LLMs")
    metadata: Optional[Any] = None
    enable_moderation: Optional[StrictBool] = None
    enable_multi_query_rag: Optional[StrictBool] = None
    enable_prompt_caching: Optional[StrictBool] = Field(default=None, description="Enable prompt caching for Anthropic models to reduce latency and cost. This disabled RAG and other dynamic parts of system prompt such as memory, current datetime, etc. Use with caution")
    enable_post_processing_system: Optional[StrictBool] = None
    enable_openai_assistant: Optional[StrictBool] = Field(default=None, description="(Deprecated) Set template mentor to openai-agent instead.")
    enable_total_grounding: Optional[StrictBool] = Field(default=None, description="Whether to force mentor to only use information within the provided documents.")
    enable_suggested_prompts: Optional[StrictBool] = Field(default=None, description="Whether to show suggested prompts for the mentor or not. Note: Suggested prompts are created by tenant admins.")
    enable_guided_prompts: Optional[StrictBool] = Field(default=None, description="Whether to show suggested prompts for the mentor or not. Note: Guided prompts are created with an llm based on chat history.")
    save_flagged_prompts: Optional[StrictBool] = None
    guided_prompt_instructions: Optional[StrictStr] = Field(default=None, description="Instructions to determine how prompt suggestions are generated.")
    google_voice: Optional[StrictInt] = None
    openai_voice: Optional[StrictInt] = None
    categories: List[MentorCategory]
    types: List[MentorType]
    is_featured: Optional[StrictBool] = Field(default=None, description="Whether the mentor is featured or not.")
    subjects: List[Subject]
    proactive_prompt: Optional[StrictStr] = Field(default=None, description="Prompt template used to start a conversation with the user when greeting_type is proactive_prompt. This will be sent to the LLM so it can respond naturally")
    study_mode_prompt: Optional[StrictStr] = Field(default=None, description="Prompt to be used to guide the user through their studies when study mode tool is enabled.")
    disclaimer: Optional[StrictStr] = Field(default=None, description="Disclaimer to be shown to the user when the mentor is used.")
    enable_disclaimer: Optional[StrictBool] = None
    show_attachment: Optional[StrictBool] = Field(default=None, description="Show attachments on mentor.")
    show_voice_call: Optional[StrictBool] = Field(default=None, description="Show voice call button on mentor.")
    show_voice_record: Optional[StrictBool] = Field(default=None, description="Show voice recording button on mentor.")
    show_rag_images: Optional[StrictBool] = Field(default=None, description="Show RAG images in mentor response.")
    starter_prompts: Optional[StarterPromptsB04Enum] = Field(default=None, description="Type of starter prompts to show: guided_prompt or suggested_prompt.  * `guided_prompt` - Guided Prompt * `suggested_prompt` - Suggested Prompt")
    embed_is_context_aware: Optional[StrictBool] = Field(default=None, description="Allow embedded mentor to read content on the embedded web page.")
    embed_open_by_default: Optional[StrictBool] = Field(default=None, description="Open mentor embed iframe by default.")
    embed_show_attachment: Optional[StrictBool] = Field(default=None, description="Show attachments on embedded mentor.")
    embed_show_voice_call: Optional[StrictBool] = Field(default=None, description="Show voice call button on embedded mentor.")
    embed_show_voice_record: Optional[StrictBool] = Field(default=None, description="Show voice recording button on embedded mentor.")
    show_explore_mentors: Optional[StrictBool] = Field(default=None, description="Show explore mentors option.")
    embed_icon_selection_data: Optional[Any] = Field(default=None, description="Stores embedded icon selection data for the mentor widget.")
    placeholder_prompt: Optional[StrictStr] = Field(default=None, description="Placeholder to be shown in the input text area when the mentor is used.")
    moderation_system_prompt: Optional[StrictStr] = Field(default=None, description="The prompt for the moderation system. This prompt must clearly distinguish between 'Approapriate' and 'Not Appropriate' queries.")
    post_processing_prompt: Optional[StrictStr] = Field(default=None, description="Prompt to be used to alter or modify final llm response into any desired form.")
    moderation_response: Optional[StrictStr] = Field(default=None, description="Desired feedback to return to the user when their prompt is deemed inappropriate.")
    safety_system_prompt: Optional[StrictStr] = Field(default=None, description="Prompt to check whether the models response is appropriate or not.")
    safety_response: Optional[StrictStr] = Field(default=None, description="Feedback given to the user when a model generates an inappropriate response")
    enable_safety_system: Optional[StrictBool] = None
    proactive_response: Optional[StrictStr] = Field(default=None, description="Response to start a conversation with a user.")
    greeting_method: Optional[GreetingMethodEnum] = Field(default=None, description="How the mentor should greet the user. proactive_prompt: Allow the LLM to respond to proactive_prompt msg. proactive_response: use proactive_response template without performing an LLM call.  * `proactive_prompt` - Proactive Prompt * `proactive_response` - Proactive Response")
    call_configuration: Optional[CallConfiguration] = None
    mcp_servers: List[MCPServer]
    last_accessed_by: Optional[StrictInt] = Field(default=None, description="edX user ID")
    recently_accessed_at: Optional[datetime] = None
    created_by: Optional[Annotated[str, Field(strict=True, max_length=255)]] = None
    created_at: Optional[datetime]
    updated_at: Optional[datetime]
    __properties: ClassVar[List[str]] = ["id", "name", "unique_id", "flow", "slug", "platform", "allow_anonymous", "enable_offline_mode", "metadata", "enable_moderation", "enable_multi_query_rag", "enable_prompt_caching", "enable_post_processing_system", "enable_openai_assistant", "enable_total_grounding", "enable_suggested_prompts", "enable_guided_prompts", "save_flagged_prompts", "guided_prompt_instructions", "google_voice", "openai_voice", "categories", "types", "is_featured", "subjects", "proactive_prompt", "study_mode_prompt", "disclaimer", "enable_disclaimer", "show_attachment", "show_voice_call", "show_voice_record", "show_rag_images", "starter_prompts", "embed_is_context_aware", "embed_open_by_default", "embed_show_attachment", "embed_show_voice_call", "embed_show_voice_record", "show_explore_mentors", "embed_icon_selection_data", "placeholder_prompt", "moderation_system_prompt", "post_processing_prompt", "moderation_response", "safety_system_prompt", "safety_response", "enable_safety_system", "proactive_response", "greeting_method", "call_configuration", "mcp_servers", "last_accessed_by", "recently_accessed_at", "created_by", "created_at", "updated_at"]

    @field_validator('slug')
    def slug_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

    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 Mentor 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.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "id",
            "created_at",
            "updated_at",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of each item in categories (list)
        _items = []
        if self.categories:
            for _item_categories in self.categories:
                if _item_categories:
                    _items.append(_item_categories.to_dict())
            _dict['categories'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in types (list)
        _items = []
        if self.types:
            for _item_types in self.types:
                if _item_types:
                    _items.append(_item_types.to_dict())
            _dict['types'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in subjects (list)
        _items = []
        if self.subjects:
            for _item_subjects in self.subjects:
                if _item_subjects:
                    _items.append(_item_subjects.to_dict())
            _dict['subjects'] = _items
        # override the default output from pydantic by calling `to_dict()` of call_configuration
        if self.call_configuration:
            _dict['call_configuration'] = self.call_configuration.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in mcp_servers (list)
        _items = []
        if self.mcp_servers:
            for _item_mcp_servers in self.mcp_servers:
                if _item_mcp_servers:
                    _items.append(_item_mcp_servers.to_dict())
            _dict['mcp_servers'] = _items
        # set to None if flow (nullable) is None
        # and model_fields_set contains the field
        if self.flow is None and "flow" in self.model_fields_set:
            _dict['flow'] = None

        # set to None if metadata (nullable) is None
        # and model_fields_set contains the field
        if self.metadata is None and "metadata" in self.model_fields_set:
            _dict['metadata'] = None

        # set to None if google_voice (nullable) is None
        # and model_fields_set contains the field
        if self.google_voice is None and "google_voice" in self.model_fields_set:
            _dict['google_voice'] = None

        # set to None if openai_voice (nullable) is None
        # and model_fields_set contains the field
        if self.openai_voice is None and "openai_voice" in self.model_fields_set:
            _dict['openai_voice'] = None

        # set to None if embed_icon_selection_data (nullable) is None
        # and model_fields_set contains the field
        if self.embed_icon_selection_data is None and "embed_icon_selection_data" in self.model_fields_set:
            _dict['embed_icon_selection_data'] = None

        # set to None if last_accessed_by (nullable) is None
        # and model_fields_set contains the field
        if self.last_accessed_by is None and "last_accessed_by" in self.model_fields_set:
            _dict['last_accessed_by'] = None

        # set to None if recently_accessed_at (nullable) is None
        # and model_fields_set contains the field
        if self.recently_accessed_at is None and "recently_accessed_at" in self.model_fields_set:
            _dict['recently_accessed_at'] = None

        # set to None if created_by (nullable) is None
        # and model_fields_set contains the field
        if self.created_by is None and "created_by" in self.model_fields_set:
            _dict['created_by'] = None

        # set to None if created_at (nullable) is None
        # and model_fields_set contains the field
        if self.created_at is None and "created_at" in self.model_fields_set:
            _dict['created_at'] = None

        # set to None if updated_at (nullable) is None
        # and model_fields_set contains the field
        if self.updated_at is None and "updated_at" in self.model_fields_set:
            _dict['updated_at'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "id": obj.get("id"),
            "name": obj.get("name"),
            "unique_id": obj.get("unique_id"),
            "flow": obj.get("flow"),
            "slug": obj.get("slug"),
            "platform": obj.get("platform"),
            "allow_anonymous": obj.get("allow_anonymous"),
            "enable_offline_mode": obj.get("enable_offline_mode"),
            "metadata": obj.get("metadata"),
            "enable_moderation": obj.get("enable_moderation"),
            "enable_multi_query_rag": obj.get("enable_multi_query_rag"),
            "enable_prompt_caching": obj.get("enable_prompt_caching"),
            "enable_post_processing_system": obj.get("enable_post_processing_system"),
            "enable_openai_assistant": obj.get("enable_openai_assistant"),
            "enable_total_grounding": obj.get("enable_total_grounding"),
            "enable_suggested_prompts": obj.get("enable_suggested_prompts"),
            "enable_guided_prompts": obj.get("enable_guided_prompts"),
            "save_flagged_prompts": obj.get("save_flagged_prompts"),
            "guided_prompt_instructions": obj.get("guided_prompt_instructions"),
            "google_voice": obj.get("google_voice"),
            "openai_voice": obj.get("openai_voice"),
            "categories": [MentorCategory.from_dict(_item) for _item in obj["categories"]] if obj.get("categories") is not None else None,
            "types": [MentorType.from_dict(_item) for _item in obj["types"]] if obj.get("types") is not None else None,
            "is_featured": obj.get("is_featured"),
            "subjects": [Subject.from_dict(_item) for _item in obj["subjects"]] if obj.get("subjects") is not None else None,
            "proactive_prompt": obj.get("proactive_prompt"),
            "study_mode_prompt": obj.get("study_mode_prompt"),
            "disclaimer": obj.get("disclaimer"),
            "enable_disclaimer": obj.get("enable_disclaimer"),
            "show_attachment": obj.get("show_attachment"),
            "show_voice_call": obj.get("show_voice_call"),
            "show_voice_record": obj.get("show_voice_record"),
            "show_rag_images": obj.get("show_rag_images"),
            "starter_prompts": obj.get("starter_prompts"),
            "embed_is_context_aware": obj.get("embed_is_context_aware"),
            "embed_open_by_default": obj.get("embed_open_by_default"),
            "embed_show_attachment": obj.get("embed_show_attachment"),
            "embed_show_voice_call": obj.get("embed_show_voice_call"),
            "embed_show_voice_record": obj.get("embed_show_voice_record"),
            "show_explore_mentors": obj.get("show_explore_mentors"),
            "embed_icon_selection_data": obj.get("embed_icon_selection_data"),
            "placeholder_prompt": obj.get("placeholder_prompt"),
            "moderation_system_prompt": obj.get("moderation_system_prompt"),
            "post_processing_prompt": obj.get("post_processing_prompt"),
            "moderation_response": obj.get("moderation_response"),
            "safety_system_prompt": obj.get("safety_system_prompt"),
            "safety_response": obj.get("safety_response"),
            "enable_safety_system": obj.get("enable_safety_system"),
            "proactive_response": obj.get("proactive_response"),
            "greeting_method": obj.get("greeting_method"),
            "call_configuration": CallConfiguration.from_dict(obj["call_configuration"]) if obj.get("call_configuration") is not None else None,
            "mcp_servers": [MCPServer.from_dict(_item) for _item in obj["mcp_servers"]] if obj.get("mcp_servers") is not None else None,
            "last_accessed_by": obj.get("last_accessed_by"),
            "recently_accessed_at": obj.get("recently_accessed_at"),
            "created_by": obj.get("created_by"),
            "created_at": obj.get("created_at"),
            "updated_at": obj.get("updated_at")
        })
        return _obj


