from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Group
from guardian.shortcuts import assign, remove_perm

try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local
    
_thread_locals = local()

def get_current_user():
    return getattr(_thread_locals, 'user', None)

def protect_models():
    user = get_current_user()
    for cls in ToProtect.get_models():
            protect_model(cls, user)
    
def unprotect_models():
    for cls in ToProtect.get_models():
            unprotect_model(cls)

class ToProtect(object):
    
    @staticmethod
    def get_models():
        if hasattr(ToProtect, 'cls_list'):
            return ToProtect.cls_list
        
        cls_list = []
        for cls_name in settings.USE_GROUP_PERMISSIONS:
            cls_type = ContentType.objects.get(model=cls_name.lower())
            cls_list.append(cls_type.model_class())
        ToProtect.cls_list = cls_list
        
        return cls_list

def protect_model(cls, user):   
    cls.safe_objects.user = user
    
    cls.old_save = cls.save
    cls.old_delete = cls.delete
    class_name = cls.__name__.lower()
    cls.save = change_security(user, class_name)(cls.save)
    cls.delete = change_security(user, class_name)(cls.delete)    
    
def unprotect_model(cls):    
    if hasattr(cls, 'old_save'):
        cls.save = cls.old_save 
        cls.delete = cls.old_delete 
        del cls.old_save    
        del cls.old_delete 
        
def change_security(user, cls_name):
    def wrapper(func):
        def wrapped(self, *args, **kwargs):                      
                        
            if self.pk and not user.has_perm('change_%s' % cls_name, self):
                raise AttributeError('User %s is not allowed to change object %s' % (user, self))
      
            return func(self, *args, **kwargs)
        return wrapped    
    return wrapper

def assign_project_to_groups(project, permissions):
    for elem in permissions:
        group = Group.objects.get(id=elem['group'])
        if elem['share']:
            assign('view_project', group, project)
            if elem['perms'] == 'write':
                assign('change_project', group, project)
        else:
            remove_perm('view_project', group, project)
            remove_perm('change_project', group, project) 
            