from django.core.cache import cache
from django.conf import settings
from guardian.core import ObjectPermissionChecker
from django.contrib.auth import get_user_model
from django.db.models import Q
from guardian.shortcuts import assign
from django.utils.encoding import smart_str
import re
import hashlib

User = get_user_model()

def get_cached_checker(user):
    key_name = get_key(user.username)
    
    checker = cache.get(key_name)
    if checker:
        return checker
    
    checker = ObjectPermissionChecker(user)
    cache.set(key_name, checker)
    return checker


def cached_assign(perm, user_or_group, object_inst):
    assign(perm, user_or_group, object_inst)
    
    if hasattr(user_or_group, 'username'):
        key = get_key(user_or_group.username)
    else:
        key = get_key(user_or_group.name)
        
    cache.delete(key)
    
    
def get_cached_userlist():
    userlist = cache.get('userlist')
    if userlist:
        return userlist
    
    query = Q(id=settings.ANONYMOUS_USER_ID) | Q(is_superuser=True)
    userlist = User.objects.exclude(query)
    cache.set('userlist', userlist)
    return userlist

def get_key(name):
    
    name = smart_str(name, encoding="ascii", errors="replace") 
    name = re.sub(r"[^\w\s_\-]", '', name)
    name = re.sub(r"\s+", '_', name)
    
    key = "checker_%s" % name
    if len(key) > 250:
        key = hashlib.sha512(key).hexdigest()
    
    return key
