from __future__ import unicode_literals
from mezzanine.utils.cache import (cache_key_prefix, cache_installed,
                                   cache_get, cache_set)


# Deprecated settings and their defaults.
DEPRECATED = {
    "PAGES_MENU_SHOW_ALL": True
}


class TemplateSettings(dict):
    """
    Dict wrapper for template settings. This exists only to warn when
    deprecated settings are accessed in templates.
    """

    def __getitem__(self, k):
        if k in DEPRECATED:
            from warnings import warn
            warn("%s is deprecated, please remove it from your templates" % k)
        return super(TemplateSettings, self).__getitem__(k)

    def __getattr__(self, name):
        try:
            return self.__getitem__(name)
        except KeyError:
            raise AttributeError


def settings(request=None):
    """
    Add the settings object to the template context.
    """
    from mezzanine.conf import settings
    settings_dict = None
    cache_settings = request and cache_installed()
    if cache_settings:
        cache_key = (cache_key_prefix(request, ignore_device=True) +
            "context-settings")
        settings_dict = cache_get(cache_key)
    if not settings_dict:
        settings.use_editable()
        settings_dict = TemplateSettings()
        for k in settings.TEMPLATE_ACCESSIBLE_SETTINGS:
            settings_dict[k] = getattr(settings, k, "")
        for k in DEPRECATED:
            settings_dict[k] = getattr(settings, k, DEPRECATED)
        if cache_settings:
            cache_set(cache_key, settings_dict)
    # This is basically the same as the old ADMIN_MEDIA_PREFIX setting,
    # we just use it in a few spots in the admin to optionally load a
    # file from either grappelli or Django admin if grappelli isn't
    # installed. We don't call it ADMIN_MEDIA_PREFIX in order to avoid
    # any confusion.
    if settings.GRAPPELLI_INSTALLED:
        settings_dict["MEZZANINE_ADMIN_PREFIX"] = "grappelli/"
    else:
        settings_dict["MEZZANINE_ADMIN_PREFIX"] = "admin/"
    return {"settings": settings_dict}

from __future__ import unicode_literals


# Deprecated settings and their defaults.
DEPRECATED = {
    "PAGES_MENU_SHOW_ALL": True
}


class TemplateSettings(dict):
    """
    Dict wrapper for template settings. This exists to enforce
    the restriction of settings in templates to those named in
    TEMPLATE_ACCESSIBLE_SETTINGS, and to warn about deprecated settings.
    """

    def __init__(self, settings, allowed_settings, *args, **kwargs):
        super(TemplateSettings, self).__init__(*args, **kwargs)
        self.settings = settings
        self.allowed_settings = set(allowed_settings)

    def __getattr__(self, k):
        try:
            return self.__getitem__(k)
        except KeyError:
            raise AttributeError

    def __getitem__(self, k):

        if k not in self.allowed_settings:
            raise KeyError

        if k in DEPRECATED:
            from warnings import warn
            warn("%s is deprecated. Please remove it from your templates" % k)

        try:
            return getattr(self.settings, k)
        except AttributeError:
            return super(TemplateSettings, self).__getitem__(k)


def settings(request=None):
    """
    Add the settings object to the template context.
    """
    from mezzanine.conf import settings

    allowed_settings = settings.TEMPLATE_ACCESSIBLE_SETTINGS

    template_settings = TemplateSettings(settings, allowed_settings)
    template_settings.update(DEPRECATED)

    # This is basically the same as the old ADMIN_MEDIA_PREFIX setting,
    # we just use it in a few spots in the admin to optionally load a
    # file from either grappelli or Django admin if grappelli isn't
    # installed. We don't call it ADMIN_MEDIA_PREFIX in order to avoid
    # any confusion.
    admin_prefix = "grappelli/" if settings.GRAPPELLI_INSTALLED else "admin/"
    template_settings["MEZZANINE_ADMIN_PREFIX"] = admin_prefix

    return {"settings": template_settings}

Make setting context processor lazy