"""Wrapper library providing transparent proxies to configuration objects.

This library provides wrapper classes that act as transparent proxies to ConfigurationDict,
ConfigurationList and Configuration objects. Each wrapper encapsulates the actual configuration
object in a __sconfig__ attribute and forwards method calls to it.
"""

# Development
# pylint: disable=unused-argument, unused-import, too-few-public-methods


# Please create the wrapper.py library. The principle of this library is to provide a transparent proxy to any ConfigurationDict
# or ConfigurationList.

# This Should provide a class override of the ConfigurationList, ConfigurationDict and Configuration, where an instance of those object is encapulsated
# in a __sconfig__ atribute. Then those override class have some dunders methods, directly forwarded to the
# __sconfig__ methods.


from superconf.configuration import Configuration, ConfigurationDict, ConfigurationList

# Provide high level API


class ConfigurationWrapper:
    """Base wrapper class providing transparent proxy functionality.
    
    This class implements the core proxy functionality used by all wrapper classes.
    It forwards attribute access and method calls to the wrapped configuration object.
    """

    def __init__(self, config):
        """Initialize wrapper with configuration object.
        
        Args:
            config: The configuration object to wrap
        """
        self.__sconfig__ = config

    def __getattr__(self, name):
        """Forward attribute access to wrapped config object."""
        return getattr(self.__sconfig__, name)

    def __getitem__(self, key):
        """Forward item access to wrapped config object."""
        return self.__sconfig__[key]

    def __setitem__(self, key, value):
        """Forward item assignment to wrapped config object."""
        self.__sconfig__[key] = value

    def __iter__(self):
        """Forward iteration to wrapped config object."""
        return iter(self.__sconfig__)

    def __len__(self):
        """Forward length queries to wrapped config object."""
        return len(self.__sconfig__)

    def __str__(self):
        """Forward string representation to wrapped config object."""
        return str(self.__sconfig__)

    def __repr__(self):
        """Forward detailed string representation to wrapped config object."""
        return f"{self.__class__.__name__}({repr(self.__sconfig__)})"


class ConfigurationDictWrapper(ConfigurationWrapper):
    """Wrapper for ConfigurationDict objects.
    
    Provides a transparent proxy to a ConfigurationDict instance.
    """

    def __init__(self, config=None, **kwargs):
        """Initialize with optional config object or create new one.
        
        Args:
            config: Existing ConfigurationDict instance or None
            **kwargs: Arguments to create new ConfigurationDict if config is None
        """
        if config is None:
            config = ConfigurationDict(**kwargs)
        super().__init__(config)


class ConfigurationListWrapper(ConfigurationWrapper):
    """Wrapper for ConfigurationList objects.
    
    Provides a transparent proxy to a ConfigurationList instance.
    """

    def __init__(self, config=None, **kwargs):
        """Initialize with optional config object or create new one.
        
        Args:
            config: Existing ConfigurationList instance or None
            **kwargs: Arguments to create new ConfigurationList if config is None
        """
        if config is None:
            config = ConfigurationList(**kwargs)
        super().__init__(config)


class ConfigurationWrap(ConfigurationDictWrapper):
    """Wrapper for Configuration objects.
    
    Provides a transparent proxy to a Configuration instance.
    Inherits from ConfigurationDictWrapper since Configuration extends ConfigurationDict.
    """

    def __init__(self, config=None, **kwargs):
        """Initialize with optional config object or create new one.
        
        Args:
            config: Existing Configuration instance or None
            **kwargs: Arguments to create new Configuration if config is None
        """
        if config is None:
            config = Configuration(**kwargs)
        super().__init__(config)
