"""
This module defines views for mailbox and mail address handling.

"""
from __future__ import absolute_import

from django.contrib import messages
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect
from django.utils.translation import gettext as _
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin

from domains.models import MailDomain
from gvawebcore.views import HostingPackageAndCustomerMixin

from .forms import (
    MAILBOX_OR_FORWARDS,
    AddMailAddressForm,
    ChangeMailboxPasswordForm,
    CreateMailboxForm,
    EditMailAddressForm,
)
from .models import MailAddress, MailAddressMailbox, Mailbox


class CreateMailbox(
    HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView
):
    """
    This view is used to set up new mailboxes for a customer hosting package.

    """

    model = Mailbox
    context_object_name = "mailbox"
    template_name_suffix = "_create"
    form_class = CreateMailboxForm

    def dispatch(self, request, *args, **kwargs):
        resp = super(CreateMailbox, self).dispatch(request, *args, **kwargs)
        if request.method != "POST":
            if not self.get_hosting_package().may_add_mailbox():
                resp = HttpResponseForbidden(
                    _(
                        "You are not allowed to add more mailboxes to this"
                        " hosting package"
                    )
                )
        return resp

    def get_context_data(self, **kwargs):
        context = super(CreateMailbox, self).get_context_data(**kwargs)
        context["hostingpackage"] = self.get_hosting_package()
        context["customer"] = self.get_customer_object()
        return context

    def get_form_kwargs(self):
        kwargs = super(CreateMailbox, self).get_form_kwargs()
        kwargs["hostingpackage"] = self.get_hosting_package()
        return kwargs

    def form_valid(self, form):
        mailbox = form.save()
        messages.success(
            self.request,
            _("Mailbox {mailbox} created successfully.").format(
                mailbox=mailbox.username
            ),
        )
        return redirect(self.get_hosting_package())


class ChangeMailboxPassword(
    HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, UpdateView
):
    """
    This view is used to set a new password for an existing mailbox.

    """

    context_object_name = "mailbox"
    form_class = ChangeMailboxPasswordForm
    model = Mailbox
    slug_field = "username"
    template_name_suffix = "_setpassword"

    def get_context_data(self, **kwargs):
        context = super(ChangeMailboxPassword, self).get_context_data(**kwargs)
        context["hostingpackage"] = self.get_hosting_package()
        context["customer"] = self.get_customer_object()
        return context

    def get_form_kwargs(self):
        kwargs = super(ChangeMailboxPassword, self).get_form_kwargs()
        kwargs["hostingpackage"] = self.get_hosting_package()
        return kwargs

    def form_valid(self, form):
        mailbox = form.save()
        messages.success(
            self.request,
            _("Successfully set new password for mailbox {mailbox}.").format(
                mailbox=mailbox.username
            ),
        )
        return redirect(self.get_hosting_package())


class AddMailAddress(
    HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView
):
    """
    This view is used to add a new mail address to a domain.

    """

    context_object_name = "mailaddress"
    form_class = AddMailAddressForm
    model = MailAddress
    template_name_suffix = "_create"

    def get_context_data(self, **kwargs):
        context = super(AddMailAddress, self).get_context_data(**kwargs)
        context["customer"] = self.get_customer_object()
        return context

    def get_maildomain(self):
        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])

    def get_form_kwargs(self):
        kwargs = super(AddMailAddress, self).get_form_kwargs()
        kwargs.update(
            {
                "hostingpackage": self.get_hosting_package(),
                "maildomain": self.get_maildomain(),
            }
        )
        return kwargs

    def form_valid(self, form):
        address = form.save()
        messages.success(
            self.request,
            _("Successfully added mail address {mailaddress}").format(
                mailaddress=address
            ),
        )
        return redirect(self.get_hosting_package())


class DeleteMailAddress(
    HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, DeleteView
):
    """
    This view is used to delete a mail address.

    """

    context_object_name = "mailaddress"
    model = MailAddress

    def get_maildomain(self):
        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])

    def get_context_data(self, **kwargs):
        context = super(DeleteMailAddress, self).get_context_data(**kwargs)
        context.update(
            {
                "customer": self.get_customer_object(),
                "hostingpackage": self.get_hosting_package(),
                "maildomain": self.get_maildomain(),
            }
        )
        return context

    def get_success_url(self):
        return self.get_hosting_package().get_absolute_url()


class EditMailAddress(
    HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, UpdateView
):
    """
    This view is used to edit a mail address' target mailbox or forwarding
    addresses.

    """

    context_object_name = "mailaddress"
    form_class = EditMailAddressForm
    model = MailAddress
    template_name_suffix = "_edit"

    def get_maildomain(self):
        return get_object_or_404(MailDomain, domain=self.kwargs["domain"])

    def get_context_data(self, **kwargs):
        context = super(EditMailAddress, self).get_context_data(**kwargs)
        context["customer"] = self.get_customer_object()
        return context

    def get_form_kwargs(self):
        kwargs = super(EditMailAddress, self).get_form_kwargs()
        kwargs.update(
            {
                "hostingpackage": self.get_hosting_package(),
                "maildomain": self.get_maildomain(),
            }
        )
        return kwargs

    def get_initial(self):
        initial = super(EditMailAddress, self).get_initial()
        mailaddress = self.get_object()
        if MailAddressMailbox.objects.filter(mailaddress=mailaddress).exists():
            initial["mailbox"] = mailaddress.mailaddressmailbox.mailbox
            initial["mailbox_or_forwards"] = MAILBOX_OR_FORWARDS.mailbox
        elif mailaddress.mailaddressforward_set.exists():
            initial["forwards"] = ", ".join(
                fwd.target for fwd in mailaddress.mailaddressforward_set.all()
            )
            initial["mailbox_or_forwards"] = MAILBOX_OR_FORWARDS.forwards
        return initial

    def form_valid(self, form):
        mailaddress = form.save()
        messages.success(
            self.request,
            _("Successfully updated mail address {mailaddress} " "targets.").format(
                mailaddress=mailaddress
            ),
        )
        return redirect(self.get_hosting_package())