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

"""
from __future__ import absolute_import, unicode_literals

from django import forms
from django.contrib import admin

from .models import (
    CustomerDiskSpaceOption,
    CustomerHostingPackage,
    CustomerHostingPackageDomain,
    CustomerMailboxOption,
    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 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,
    ]
    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)