# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.db.models.signals import pre_delete, pre_save
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _

try:
    from django.utils.encoding import force_text
except ImportError:
    from django.utils.encoding import force_unicode as force_text

from .shortcuts import get_usersettings_model

USERSETTINGS_CACHE = {}


class UserSettingsManager(models.Manager):

    def get_current(self):
        """
        Returns the current ``UserSettings`` based on the SITE_ID in the
        project's settings. The ``UserSettings`` object is cached the first
        time it's retrieved from the database.
        """
        from django.conf import settings
        try:
            site_id = settings.SITE_ID
        except AttributeError:
            raise ImproperlyConfigured(
                'You\'re using the Django "sites framework" without having '
                'set the SITE_ID setting. Create a site in your database and '
                'set the SITE_ID setting to fix this error.')

        try:
            current_usersettings = USERSETTINGS_CACHE[site_id]
        except KeyError:
            current_usersettings = self.get(site_id=site_id)
            USERSETTINGS_CACHE[site_id] = current_usersettings
        return current_usersettings

    def clear_cache(self):
        """Clears the ``UserSettings`` object cache."""
        global USERSETTINGS_CACHE
        USERSETTINGS_CACHE = {}


@python_2_unicode_compatible
class EmptyUserSetting(object):
    """
    This fake `UserSettings` objects will be returned by
    the `get_current_usersettings()` if a `usersettings`
    object `DoesNotExist` for the current site.
    """

    id = None
    pk = None

    def __init__(self):
        pass

    def __str__(self):
        return 'User Setting not defined for current site'

    def save(self, force_insert=False, force_update=False):
        raise NotImplementedError('EmptyUserSettings cannot be saved.')

    def delete(self):
        raise NotImplementedError('EmptyUserSettings cannot be deleted.')


class UserSettings(models.Model):
    site = models.OneToOneField(
        Site, editable=False, null=True, related_name='usersettings')
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, editable=False, related_name='usersettings')
    created = models.DateTimeField(_('Created at'), auto_now_add=True)
    modified = models.DateTimeField(_('Last Updated'), auto_now=True)

    objects = UserSettingsManager()

    class Meta:
        verbose_name = _('User Setting')
        verbose_name_plural = _('User Settings')
        abstract = True

    def __str__(self):
        return force_text(self.site)

    @classmethod
    def get_default(self):
        """
        Returns the default object for usersettings.
        """
        return EmptyUserSetting()


def clear_usersettings_cache(sender, **kwargs):
    """
    Clears the cache (if primed) each time a ``UserSettings`` is saved or deleted
    """
    instance = kwargs['instance']
    try:
        del USERSETTINGS_CACHE[instance.site.pk]
    except KeyError:
        pass


import django
from distutils.version import LooseVersion

if LooseVersion(django.get_version()) < LooseVersion('1.7'):
    pre_save.connect(clear_usersettings_cache, sender=get_usersettings_model())
    pre_delete.connect(clear_usersettings_cache, sender=get_usersettings_model())