# 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 Connection(ABC):
    """Connection configuration for AI agents.
    `provider`, `kind`, and `endpoint` are required properties here,
    but this section can accept additional via options.

    Attributes
    ----------
    kind : str
        The Authentication kind for the AI service (e.g., 'key' for API key, 'oauth' for OAuth tokens)
    authenticationMode : str
        The authority level for the connection, indicating under whose authority the connection is made (e.g., 'user', 'agent', 'system')
    usageDescription : Optional[str]
        The usage description for the connection, providing context on how this connection will be used
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="")
    authenticationMode: str = field(default="system")
    usageDescription: Optional[str] = None

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

        """

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

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

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

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

    @staticmethod
    def load_kind(data: dict, context: Optional[LoadContext]) -> "Connection":
        # load polymorphic Connection instance
        if data is not None and "kind" in data:
            discriminator_value = str(data["kind"]).lower()
            if discriminator_value == "reference":
                return ReferenceConnection.load(data, context)
            elif discriminator_value == "remote":
                return RemoteConnection.load(data, context)
            elif discriminator_value == "key":
                return ApiKeyConnection.load(data, context)
            elif discriminator_value == "anonymous":
                return AnonymousConnection.load(data, context)

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

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

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

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

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the Connection 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 Connection 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 ReferenceConnection(Connection):
    """Connection configuration for AI services using named connections.

    Attributes
    ----------
    kind : str
        The Authentication kind for the AI service (e.g., 'key' for API key, 'oauth' for OAuth tokens)
    name : str
        The name of the connection
    target : Optional[str]
        The target resource or service that this connection refers to
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="reference")
    name: str = field(default="")
    target: Optional[str] = None

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

        """

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

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

        # create new instance
        instance = ReferenceConnection()

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

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

        return result

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the ReferenceConnection 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 ReferenceConnection 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 RemoteConnection(Connection):
    """Connection configuration for AI services using named connections.

    Attributes
    ----------
    kind : str
        The Authentication kind for the AI service (e.g., 'key' for API key, 'oauth' for OAuth tokens)
    name : str
        The name of the connection
    endpoint : str
        The endpoint URL for the AI service
    """

    _shorthand_property: ClassVar[Optional[str]] = None

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

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

        """

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

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

        # create new instance
        instance = RemoteConnection()

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

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

        return result

    def to_yaml(self, context: Optional[SaveContext] = None) -> str:
        """Convert the RemoteConnection 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 RemoteConnection 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 ApiKeyConnection(Connection):
    """Connection configuration for AI services using API keys.

    Attributes
    ----------
    kind : str
        The Authentication kind for the AI service (e.g., 'key' for API key, 'oauth' for OAuth tokens)
    endpoint : str
        The endpoint URL for the AI service
    apiKey : str
        The API key for authenticating with the AI service
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="key")
    endpoint: str = field(default="")
    apiKey: str = field(default="")

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

        """

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

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

        # create new instance
        instance = ApiKeyConnection()

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

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

        return result

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

    Attributes
    ----------
    kind : str
        The Authentication kind for the AI service (e.g., 'key' for API key, 'oauth' for OAuth tokens)
    endpoint : str
        The endpoint for authenticating with the AI service
    """

    _shorthand_property: ClassVar[Optional[str]] = None

    kind: str = field(default="anonymous")
    endpoint: str = field(default="")

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

        """

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

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

        # create new instance
        instance = AnonymousConnection()

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

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

        return result

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