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


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

from ._context import LoadContext, SaveContext


@dataclass
class Resource(ABC):
    """Represents a resource required by the agent
    Resources can include databases, APIs, or other external systems
    that the agent needs to interact with to perform its tasks

    Attributes
    ----------
    name : str
        Name of the resource
    kind : str
        The kind of resource (e.g., model, tool)
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    name: str = field(default="")
    kind: str = field(default="")

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

        """

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

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

        # load polymorphic Resource instance
        instance = Resource.load_kind(data, context)

        if data is not None and "name" in data:
            instance.name = data["name"]
        if data is not None and "kind" in data:
            instance.kind = data["kind"]
        if context is not None:
            instance = context.process_output(instance)
        return instance

    @staticmethod
    def load_kind(data: dict, context: Optional[LoadContext]) -> "Resource":
        # load polymorphic Resource instance
        if data is not None and "kind" in data:
            discriminator_value = str(data["kind"]).lower()
            if discriminator_value == "model":
                return ModelResource.load(data, context)
            elif discriminator_value == "tool":
                return ToolResource.load(data, context)

            else:
                raise ValueError(
                    f"Unknown Resource discriminator value: {discriminator_value}"
                )
        else:

            raise ValueError("Missing Resource discriminator property: 'kind'")

    def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]:
        """Save the Resource 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.name is not None:
            result["name"] = obj.name
        if obj.kind is not None:
            result["kind"] = obj.kind

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

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the Resource 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 Resource 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)


@dataclass
class ModelResource(Resource):
    """Represents a model resource required by the agent

    Attributes
    ----------
    kind : str
        The kind identifier for model resources
    id : str
        The unique identifier of the model resource
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="model")
    id: str = field(default="")

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

        """

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

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

        # create new instance
        instance = ModelResource()

        if data is not None and "kind" in data:
            instance.kind = data["kind"]
        if data is not None and "id" in data:
            instance.id = data["id"]
        if context is not None:
            instance = context.process_output(instance)
        return instance

    def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]:
        """Save the ModelResource 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)

        # Start with parent class properties
        result = super().save(context)

        if obj.kind is not None:
            result["kind"] = obj.kind
        if obj.id is not None:
            result["id"] = obj.id

        return result

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the ModelResource 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 ModelResource 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)


@dataclass
class ToolResource(Resource):
    """Represents a tool resource required by the agent

    Attributes
    ----------
    kind : str
        The kind identifier for tool resources
    id : str
        The unique identifier of the tool resource
    options : dict[str, Any]
        Configuration options for the tool resource
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="tool")
    id: str = field(default="")
    options: dict[str, Any] = field(default_factory=dict)

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

        """

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

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

        # create new instance
        instance = ToolResource()

        if data is not None and "kind" in data:
            instance.kind = data["kind"]
        if data is not None and "id" in data:
            instance.id = data["id"]
        if data is not None and "options" in data:
            instance.options = data["options"]
        if context is not None:
            instance = context.process_output(instance)
        return instance

    def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]:
        """Save the ToolResource 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)

        # Start with parent class properties
        result = super().save(context)

        if obj.kind is not None:
            result["kind"] = obj.kind
        if obj.id is not None:
            result["id"] = obj.id
        if obj.options is not None:
            result["options"] = obj.options

        return result

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the ToolResource 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 ToolResource 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)
