"""
This module contains the admin site interface for hosting packages.

"""
from __future__ import absolute_import

from django import forms
from django.contrib import admin

from .models import (
    CustomerDiskSpaceOption,
    CustomerHostingPackage,
    CustomerHostingPackageDomain,
    CustomerMailboxOption,
    CustomerPackageDiskUsage,
    CustomerUserDatabaseOption,
    DiskSpaceOption,
    HostingPackageTemplate,
    MailboxOption,
    UserDatabaseOption,
)


class CustomerHostingPackageCreateForm(forms.ModelForm):
    """
    This is the form class for creating new customer hosting packages.

    """

    class Meta:
        model = CustomerHostingPackage
        fields = ["customer", "template", "name"]

    def save(self, **kwargs):
        """
        Save the customer hosting package.

        :param kwargs: keyword arguments passed to create method
        :return: customer hosting package instance
        :rtype: :py:class:`hostingpackages.models.CustomerHostingPackage`

        """
        hostinpackages = CustomerHostingPackage.objects.create_from_template(
            customer=self.cleaned_data["customer"],
            template=self.cleaned_data["template"],
            name=self.cleaned_data["name"],
            **kwargs
        )
        return hostinpackages

    def save_m2m(self):
        pass


class CustomerDiskSpaceOptionInline(admin.TabularInline):
    """
    This class implements the inline editor for customer hosting package disk
    space options.

    """

    model = CustomerDiskSpaceOption
    extra = 0


class CustomerMailboxOptionInline(admin.TabularInline):
    """
    This class implements the inline editor for customer hosting package
    mailbox options.

    """

    model = CustomerMailboxOption
    extra = 0


class CustomerUserDatabaseOptionInline(admin.TabularInline):
    """
    This class implements the inline editor for customer hosting package user
    database options.

    """

    model = CustomerUserDatabaseOption
    extra = 0


class CustomerHostingPackageDomainInline(admin.TabularInline):
    """
    This class implements the inline editor for assigning hosting domains to
    hosting packages.

    """

    model = CustomerHostingPackageDomain
    extra = 0


class CustomerPackageDiskUsageInline(admin.TabularInline):
    model = CustomerPackageDiskUsage
    ordering = ["-used_kb", "source", "item"]
    fields = ["source", "item", "used_kb"]
    readonly_fields = ["source", "item", "used_kb"]
    extra = 0
    can_delete = False

    def has_add_permission(self, request, obj):
        return False


class CustomerHostingPackageAdmin(admin.ModelAdmin):
    """
    This class implements the admin interface for
    :py:class:`CustomerHostingPackage`.

    """

    add_form = CustomerHostingPackageCreateForm
    add_fieldsets = ((None, {"fields": ("customer", "template", "name")}),)

    inlines = [
        CustomerDiskSpaceOptionInline,
        CustomerMailboxOptionInline,
        CustomerUserDatabaseOptionInline,
        CustomerHostingPackageDomainInline,
        CustomerPackageDiskUsageInline,
    ]
    list_display = ["name", "customer", "osuser"]

    def get_form(self, request, obj=None, **kwargs):
        """
        Use special form for customer hosting package creation.

        :param request: the current HTTP request
        :param obj: either a :py:class:`CustomerHostingPackage
            <hostingpackages.models.CustomerHostingPackage>` instance or None
            for a new customer hosting package
        :param kwargs: keyword arguments to be passed to
            :py:meth:`django.contrib.admin.ModelAdmin.get_form`
        :return: form instance

        """
        defaults = {}
        if obj is None:
            defaults.update(
                {
                    "form": self.add_form,
                    "fields": admin.options.flatten_fieldsets(self.add_fieldsets),
                }
            )
        defaults.update(kwargs)
        return super(CustomerHostingPackageAdmin, self).get_form(
            request, obj, **defaults
        )

    def get_readonly_fields(self, request, obj=None):
        """
        Make sure that customer and template are not editable for existing
        customer hosting packages.

        :param request: the current HTTP request
        :param obj: either a :py:class:`CustomerHostingPackage
            <hostingpackages.models.CustomerHostingPackage>` instance or None
            for a new customer hosting package
        :return: a list of fields
        :rtype: list

        """
        if obj:
            return ["customer", "template"]
        return []


admin.site.register(CustomerHostingPackage, CustomerHostingPackageAdmin)
admin.site.register(DiskSpaceOption)
admin.site.register(HostingPackageTemplate)
admin.site.register(MailboxOption)
admin.site.register(UserDatabaseOption)
