from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.db import transaction
from django.http import HttpResponseServerError
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from guardian.shortcuts import (remove_perm, get_objects_for_group, 
    get_objects_for_user)
from ldt.ldt_utils.forms import GroupAddForm
from ldt.security.cache import get_cached_checker, cached_assign
from ldt.security.utils import add_change_attr, get_userlist, get_userlist_group
from ldt.user.forms import PictureForm

User = get_user_model()

@login_required
def get_group_projects_view(request):
    
    grp_id = request.POST["id_group"]
    project_list = get_group_projects(request.user, grp_id)
    
    is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);

    return render_to_response("ldt/ldt_utils/partial/projectslist.html",
                              {'projects': project_list, 'show_username':True,
                               'is_gecko': is_gecko, 'group_id': grp_id},
                              context_instance=RequestContext(request))


def get_group_projects(user, grp_id, exclude_owner=True, exclude_front=True):
    
    # Get group, user and project_list
    if grp_id == "-1":
        if exclude_owner:
            project_list = get_objects_for_user(user, 'ldt_utils.view_project', use_groups=False).exclude(owner=user).select_related("owner")
        else:
            project_list = get_objects_for_user(user, 'ldt_utils.view_project', use_groups=False).select_related("owner")
    else:
        grp = Group.objects.get(id=grp_id)
        if exclude_front:
            project_list = get_objects_for_group(grp, 'ldt_utils.view_project').exclude(title__startswith='front').select_related("owner")
        else:
            project_list = get_objects_for_group(grp, 'ldt_utils.view_project').select_related("owner")
    project_list = add_change_attr(user, project_list)
    
    return project_list


@login_required
@transaction.atomic
def create_group(request):
    if not request.user.has_perm('auth.add_group'):
        return HttpResponseServerError('<h1>User %s can not create a group.</h1>' % request.user.username)

    form_status = ''
    
    if request.method == 'POST':
        form = GroupAddForm(request.POST)
        picture_form = PictureForm(None, request.POST, request.FILES)
        submit_action = request.REQUEST.get("submit_button", False)
        
        if submit_action == 'close':
            return redirect("groups-view")
        else:    
            if form.is_valid():        
                name = form.cleaned_data['name']
                members_list = form.cleaned_data['read_list']
                admin_list = form.cleaned_data['write_list']          
                
                group = Group.objects.create(name=name)
                group.save()
                group.profile.description = form.cleaned_data['description']
                group.profile.save()
                
                picture_form.model = group
                if picture_form.is_valid():
                    picture_form.save()
               
                    cached_assign('is_owner_group', request.user, group)
                    cached_assign('change_group', request.user, group)
                    request.user.groups.add(group)             
        
                    for elem in members_list:
                        if hasattr(elem, 'username'):
                            elem.groups.add(group)
                            if elem in admin_list:
                                cached_assign('change_group', elem, group)
                    form_status = 'saved'
                else:
                    group.delete()
    else:
        form = GroupAddForm()
        picture_form = PictureForm()
    
    if form_status == 'saved':
        return redirect("groups-view")
        
    return render_to_response("ldt/ldt_utils/create_group.html", {'group_edition': True, 'form' : form, 'form_status' : form_status, 
                                                                  'elem_list' : get_userlist(request.user), 'profile_picture_form': picture_form}, context_instance=RequestContext(request))

@login_required
@transaction.atomic
def update_group(request, group_id):
    group = get_object_or_404(Group, id=group_id)
    checker = get_cached_checker(request.user)
    
    if not checker.has_perm('change_group', group):
        form_status = 'none'
        return render_to_response("ldt/ldt_utils/create_group.html", {'form_status' : form_status}, context_instance=RequestContext(request))

    form_status = ''
    is_owner_group = checker.has_perm('is_owner_group', group)     
            
    if request.method == "POST":
        form = GroupAddForm(request.POST, instance=group)
        picture_form = PictureForm(group, request.POST, request.FILES)
        submit_action = request.REQUEST.get("submit_button", False)
        
        if submit_action == 'delete':
            if is_owner_group:
                group.delete()
                form_status = 'deleted'
        elif submit_action == 'close':
            return redirect("groups-view")
        else:   
            if form.is_valid() and picture_form.is_valid():
                name = form.cleaned_data['name']
                new_member_list = form.cleaned_data['read_list']
                old_member_list = User.objects.filter(groups=group).exclude(id=request.user.id)
                admin_list = form.cleaned_data['write_list']
                group.name = name
                group.profile.description = form.cleaned_data['description']
                group.profile.save()

                for user in new_member_list:
                    if not hasattr(user, 'username'):
                        raise AttributeError('new_member_list should only contain users')
                    if user != request.user:
                        user.groups.add(group)
                        if is_owner_group:
                            if user in admin_list:
                                cached_assign('change_group', user, group)
                            else:
                                remove_perm('change_group', user, group)
                                
                for user in old_member_list:
                    if user not in new_member_list:
                        user.groups.remove(group)
                        remove_perm('change_group', user, group)
                                        
                group.save()
                picture_form.save()
                form_status = 'saved'                   
    else:
        form = GroupAddForm(initial={'name':unicode(group.name)}) 
        picture_form = PictureForm()   

    if form_status == 'deleted' or form_status == 'saved':
        return redirect("groups-view")
    else:
        member_list, admin_list = get_userlist_group(group, request.user)
        profile_image = group.profile
        
    return render_to_response("ldt/ldt_utils/create_group.html", {'group_id' : group_id, 'form' : form, 'form_status' : form_status, 'group_edition': True,
                                                                  'elem_list' : get_userlist(request.user), 'member_list': member_list, 'admin_list': admin_list,
                                                                  'is_owner_group': is_owner_group, 'profile_picture_form': picture_form, 'img_container': profile_image}, context_instance=RequestContext(request))
    
    
    
@login_required
def groups_filter(request, filter):
    if filter and len(filter) > 0 and filter[0] == '_':
        filter = filter[1:]

    if filter:
        group_list = request.user.groups.filter(name__icontains=filter)
        search_active = True 
    else:
        group_list = request.user.groups.all()
        search_active = False
        
    group_list = group_list.exclude(name=settings.PUBLIC_GROUP_NAME)
    group_list = sorted(group_list.all(), key=lambda group: group.name.lower())
    group_list = add_change_attr(request.user, group_list)
    
    
    return render_to_response("ldt/ldt_utils/partial/groupslist.html",
                              {'groups': group_list, 'search_active': search_active},
                              context_instance=RequestContext(request))
    
