from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.models import User, Group
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django import forms as forms

from mail.models import Domain, Account, Address
from mail.forms import DomainForm, AccountForm, AddressForm, DeleteForm, \
        RequestNewDomainForm
from mail.utils import form_to_model_save

def get_data(user):
    """returns three querysets the user has access to
    all domains this user manages
    all accounts this user manages
    all groups this user belongs to
    """
    groups = user.groups.all()
    domains = Domain.objects.filter(admins__in=groups)
    accounts = Account.objects.filter(admins__in=groups)

    return (domains, accounts, groups)

@login_required
def index(request):
    """Renders the standard view which containts domains and accounts"""
    domains, accounts, groups = get_data(request.user)
    reqdomain = RequestNewDomainForm()
    if request.method == 'POST':
        reqdomain = RequestNewDomainForm(request.POST)
        if reqdomain.is_valid():
            from django.core.mail import send_mail
            from django.conf import settings

            domain = reqdomain.cleaned_data['name']
            subject = "User %s requests new domain %s" % (request.user, domain)
            sender = request.user.email
            recp = ["%s <%s>" % x for x in settings.ADMINS]
            message = """
            User %s requests domain %s
            Answers on a postcard to %s please
            """ % (request.user, domain, request.user.email)

            send_mail(subject, message, sender,
                        recp, fail_silently=False)

    return render_to_response('index.html', {'domains': domains, 'accounts': accounts, 'reqdomain': reqdomain})

@permission_required('mail.change_address')
@permission_required('mail.add_address')
def domain_detail(request, domain):
    """Domain detail view
    Lists all addresses related to the domain
    En/disables the domain
    """
    domains, accounts, groups = get_data(request.user)
    domain = get_object_or_404(domains, name=domain)
    if request.method == 'POST':
        form = DomainForm(request.POST, groups=groups)
        # TODO: validation, incl. permissions!
        if form.is_valid():
            form_to_model_save(domain, form)
            return HttpResponseRedirect(reverse('mail_domain_detail',
                kwargs={'domain': domain.name}))
    else:
        form = DomainForm(instance=domain, groups=groups)
        return render_to_response('domain_detail.html',
                {'form': form, 'domain': domain})

@login_required
@permission_required('mail.change_address')
@permission_required('mail.add_address')
def address_edit(request, domain, address=None):
    """Address edit view
    Lists and edits all addresses in the current domain
    """
    domains, accounts, groups = get_data(request.user)
    domain = get_object_or_404(domains, name=domain)

    # either create a new empty address in the current domain
    # or edit an existing one
    if address is None:
        address = Address(domain=domain)
    else:
        address = domain.address_set.get(address=address)

    if request.method == 'POST':
        form = AddressForm(data=request.POST, groups=groups)
        if form.is_valid():
            form_to_model_save(address, form)
            return HttpResponseRedirect(reverse('mail_domain_detail',
                kwargs={'domain': domain.name}))
    else:
        form = AddressForm(instance=address, groups=groups)
        #form.fields['accounts'].queryset = accounts
    return render_to_response('mail_edit.html', {'form': form,
        'domain': domain,
        'address': address})

@login_required
@permission_required('mail.change_account')
@permission_required('mail.add_account')
def account_edit(request, account=None):
    domains, accounts, groups = get_data(request.user)

    # either create a new empty address in the current domain
    # or edit an existing one
    if account is None:
        account = Account()
    else:
        account = get_object_or_404(accounts, name=account)

    if request.method == 'POST':
        form = AccountForm(instance=account, data=request.POST, groups=groups)
        if form.is_valid():
            form_to_model_save(account, form)
            return HttpResponseRedirect(reverse('mail_index'))
    else:
        form = AccountForm(instance=account, groups=groups)
        #form.fields['accounts'].queryset = accounts
    return render_to_response('mail_edit.html', {'form': form,
        'account': account})

@login_required
@permission_required('mail.delete_address')
def address_delete(request, domain, address, doit=False):
    """Deletes an address"""
    domains, accounts, groups = get_data(request.user)
    domain = get_object_or_404(domains, name=domain)
    address = domain.address_set.get(address=address)

    if doit:
        address.delete()
        return HttpResponseRedirect(reverse('mail_domain_detail',
            kwargs={'domain': domain.name}))
    else:
        form = DeleteForm()
        if request.method == 'POST':
            form = DeleteForm(request.POST)
            if form.is_valid():
                address.delete()
                return HttpResponseRedirect(reverse('mail_domain_detail',
                    kwargs={'domain': domain.name}))
    return render_to_response('mail_delete.html', {'form': form,
        'domain': domain,
        'what': address})

@login_required
def account_delete(request, account, doit=False):
    """Deletes an account"""
    domains, accounts, groups = get_data(request.user)
    account = get_object_or_404(accounts, name=account)

    if doit:
        account.delete()
        return HttpResponseRedirect(reverse('mail_index'))
    else:
        form = DeleteForm()
        if request.method == 'POST':
            form = DeleteForm(request.POST)
            if form.is_valid():
                account.delete()
                return HttpResponseRedirect(reverse('mail_index'))
    return render_to_response('mail_delete.html', {'form': form,
        'what': account})

def accound_delete(request):
    return HttpResponseRedirect(reverse('mail_domain_detail'))

