# -*- coding: utf-8 -*-

"""
Singleton pattern decorator for ensuring single
instance classes.
"""

from functools import wraps
from typing import Any, Callable, Optional, Type


# pylint: disable=too-few-public-methods
class _SingletonWrapper:
    """Wrapper class to ensure only one instance of decorated class."""

    def __init__(self, cls: Type) -> None:
        self.cls = cls
        self.instance: Optional[Any] = None
        wraps(cls)(self)

    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        if self.instance is None:
            self.instance = self.cls(*args, **kwargs)
        return self.instance


def singleton(cls: Type) -> Callable:
    """
    Make a class a Singleton class (only one instance)

    :param cls: The class being decorated.
    :type cls: ``Type``
    :return: The wrapped function.
    :rtype: Callable
    """
    return _SingletonWrapper(cls)
