"""
Caching related utility classes and functions.
"""
import hashlib

from edx_django_utils.cache import TieredCache

DEFAULT_TIMEOUT = 60 * 60  # 1 hour


def get_key(*args, **kwargs):
    """
    Get MD5 encoded cache key for given positional and keyword arguments.

    MD5 encrytion is applied to a key that is generated by concatenating the positional and keyword arguments.
    Following is the format of the generated key from arguments before applying the MD5 encryption.
        arg1__arg2__key1:value1__key2:value2 ...

    Example:
        >>> get_key('ecommerce', site_domain='example.com', resource='catalogs')
        1892cd85a30b8fc9180369c17b472c38
        >>> # The generated key for the above call before applying MD5 encryption will be as follows
        >>> # "ecommerce__site_domain:example.com__resource:catalogs"

    Arguments:
        *args: Arguments that need to be present in cache key.
        **kwargs: Key word arguments that need to be present in cache key.

    Returns:
         (str): An MD5 encoded key uniquely identified by the key word arguments.
    """
    key = '{}__{}'.format(
        '__'.join(map(str, args)),
        '__'.join(['{}:{}'.format(item, str(value)) for item, value in kwargs.items()])
    )

    return hashlib.md5(key.encode('utf-8')).hexdigest()


def get(key):
    """
    Get value from cache for given key.

    Returns:
        (CachedResponse): CachedResponse object.
    """
    return TieredCache.get_cached_response(key)


def set(key, value, timeout=DEFAULT_TIMEOUT):  # pylint: disable=redefined-builtin
    """
    Set value in cache for given key.

    Arguments:
        key (str): Cache key.
        value (object): Value to be stored in cache.
        timeout (int): Cache timeout in seconds.
    """
    TieredCache.set_all_tiers(key, value, django_cache_timeout=timeout)
