"""
Global configuration for deployment settings.

This allows passing information from deploy() to all executions, tasks, and steps.
"""
from dataclasses import dataclass, field
from enum import StrEnum
from typing import Any, Optional


class InputOutputTypes(StrEnum):
    """Types for input/output configuration."""
    API = 'API'
    QUEUE = 'QUEUE'
    FILA = 'FILA'
    FTP = 'FTP'


@dataclass
class Credential:
    """Credential configuration."""
    key: str
    value: str
    encrypted: bool = False


@dataclass
class ConfigObject:
    """Platform configuration object.

    This object contains all configuration received from the platform.
    Access properties using dot notation: config.inputPath, config.credentials, etc.
    """
    instanceId: str = ""
    executionId: str = ""
    automationName: str = ""
    clientId: str = ""
    userId: str = ""
    outputPath: str = ""
    inputPath: str = ""
    inputMetaData: Optional[dict[str, Any]] = None
    inputType: InputOutputTypes = InputOutputTypes.FTP
    outputType: InputOutputTypes = InputOutputTypes.FTP
    outputMetaData: Optional[dict[str, Any]] = None
    keepAlive: bool = False
    keepAliveInterval: Optional[int] = None
    credentials: list[Credential] = field(default_factory=list)

    def get_credential(self, key: str) -> Optional[str]:
        """Get a credential value by key.

        Args:
            key (str): The credential key (e.g., 'username', 'password').

        Returns:
            Optional[str]: The credential value or None if not found.
        """
        for cred in self.credentials:
            if cred.key == key:
                return cred.value
        return None


class DeploymentConfig:
    """Global deployment configuration."""

    def __init__(self) -> None:
        """Initialize deployment configuration."""
        self._config: dict[str, Any] = {}

    def set(self, key: str, value: Any) -> None:
        """Set a configuration value.

        Args:
            key (str): Configuration key.
            value (Any): Configuration value.
        """
        self._config[key] = value

    def get(self, key: str, default: Any = None) -> Any:
        """Get a configuration value.

        Args:
            key (str): Configuration key.
            default (Any, optional): Default value if key not found. Defaults to None.

        Returns:
            Any: Configuration value or default.
        """
        return self._config.get(key, default)

    def update(self, config: dict[str, Any]) -> None:
        """Update multiple configuration values.

        Args:
            config (dict[str, Any]): Dictionary of configuration values.
        """
        self._config.update(config)

    def clear(self) -> None:
        """Clear all configuration."""
        self._config.clear()

    def to_dict(self) -> dict[str, Any]:
        """Get all configuration as dict.

        Returns:
            dict[str, Any]: Copy of all configuration values.
        """
        return self._config.copy()


_deployment_config = DeploymentConfig()


def get_deployment_config() -> DeploymentConfig:
    """Get the global deployment configuration.

    Returns:
        DeploymentConfig: Global deployment configuration instance.
    """
    return _deployment_config


def set_deployment_config(**kwargs: Any) -> None:
    """Set deployment configuration values.

    Args:
        **kwargs (Any): Configuration key-value pairs.
    """
    _deployment_config.update(kwargs)


def _get_config_value(key: str, default: Any = None) -> Any:
    """Get a deployment configuration value (internal use).

    Args:
        key (str): Configuration key.
        default (Any, optional): Default value if key not found. Defaults to None.

    Returns:
        Any: Configuration value or default.
    """
    return _deployment_config.get(key, default)


def get_config_object() -> Optional[ConfigObject]:
    """Get the full Config object from the platform.

    Returns:
        Optional[ConfigObject]: The complete Config object with all fields, or None if not set.

    Example:
        config = get_config_object()
        if config:
            print(config.inputPath)
            print(config.outputPath)
            username = config.get_credential('username')
    """
    return _deployment_config.get('_config_obj')
