# 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 ._Format import Format
from ._Parser import Parser


@dataclass
class Template:
    """Template model for defining prompt templates.

    This model specifies the rendering engine used for slot filling prompts,
    the parser used to process the rendered template into API-compatible format,
    and additional options for the template engine.

    It allows for the creation of reusable templates that can be filled with dynamic data
    and processed to generate prompts for AI models.

    Attributes
    ----------
    format : Format
        Template rendering engine used for slot filling prompts (e.g., mustache, jinja2)
    parser : Parser
        Parser used to process the rendered template into API-compatible format
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    format: Format = field(default_factory=Format)
    parser: Parser = field(default_factory=Parser)

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

        """

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

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

        # create new instance
        instance = Template()

        if data is not None and "format" in data:
            instance.format = Format.load(data["format"], context)
        if data is not None and "parser" in data:
            instance.parser = Parser.load(data["parser"], 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 Template 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.format is not None:
            result["format"] = obj.format.save(context)
        if obj.parser is not None:
            result["parser"] = obj.parser.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 Template 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 Template 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)
