# Copyright (c) Microsoft. All rights reserved.
# WARNING: This is an auto-generated file. DO NOT EDIT THIS FILE DIRECTLY.


from dataclasses import dataclass, field
from typing import Any, ClassVar, Optional

from ._context import LoadContext, SaveContext
from ._Connection import Connection
from ._ModelOptions import ModelOptions


@dataclass
class Model:
    """Model for defining the structure and behavior of AI agents.
    This model includes properties for specifying the model's provider, connection details, and various options.
    It allows for flexible configuration of AI models to suit different use cases and requirements.

    Attributes
    ----------
    id : str
        The unique identifier of the model - can be used as the single property shorthand
    provider : Optional[str]
        The provider of the model (e.g., 'openai', 'azure', 'anthropic')
    apiType : Optional[str]
        The type of API to use for the model (e.g., 'chat', 'response', etc.)
    connection : Optional[Connection]
        The connection configuration for the model
    options : Optional[ModelOptions]
        Additional options for the model
    """

    _shorthand_property: ClassVar[Optional[str]] = "id"

    id: str = field(default="")
    provider: Optional[str] = None
    apiType: Optional[str] = None
    connection: Optional[Connection] = None
    options: Optional[ModelOptions] = None

    @staticmethod
    def load(data: Any, context: Optional[LoadContext] = None) -> "Model":
        """Load a Model instance.
        Args:
            data (Any): The data to load the instance from.
            context (Optional[LoadContext]): Optional context with pre/post processing callbacks.
        Returns:
            Model: The loaded Model instance.

        """

        if context is not None:
            data = context.process_input(data)

        # handle alternate representations
        if isinstance(data, str):
            data = {"id": data}

        if not isinstance(data, dict):
            raise ValueError(f"Invalid data for Model: {data}")

        # create new instance
        instance = Model()

        if data is not None and "id" in data:
            instance.id = data["id"]
        if data is not None and "provider" in data:
            instance.provider = data["provider"]
        if data is not None and "apiType" in data:
            instance.apiType = data["apiType"]
        if data is not None and "connection" in data:
            instance.connection = Connection.load(data["connection"], context)
        if data is not None and "options" in data:
            instance.options = ModelOptions.load(data["options"], context)
        if context is not None:
            instance = context.process_output(instance)
        return instance

    def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]:
        """Save the Model instance to a dictionary.
        Args:
            context (Optional[SaveContext]): Optional context with pre/post processing callbacks.
        Returns:
            dict[str, Any]: The dictionary representation of this instance.

        """
        obj = self
        if context is not None:
            obj = context.process_object(obj)

        result: dict[str, Any] = {}

        if obj.id is not None:
            result["id"] = obj.id
        if obj.provider is not None:
            result["provider"] = obj.provider
        if obj.apiType is not None:
            result["apiType"] = obj.apiType
        if obj.connection is not None:
            result["connection"] = obj.connection.save(context)
        if obj.options is not None:
            result["options"] = obj.options.save(context)

        if context is not None:
            result = context.process_dict(result)
        return result

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the Model instance to a YAML string.
        Args:
            context (Optional[SaveContext]): Optional context with pre/post processing callbacks.
        Returns:
            str: The YAML string representation of this instance.

        """
        if context is None:
            context = SaveContext()
        return context.to_yaml(self.save(context))

    def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str:
        """Convert the Model instance to a JSON string.
        Args:
            context (Optional[SaveContext]): Optional context with pre/post processing callbacks.
            indent (int): Number of spaces for indentation. Defaults to 2.
        Returns:
            str: The JSON string representation of this instance.

        """
        if context is None:
            context = SaveContext()
        return context.to_json(self.save(context), indent)
