"""
This module contains models related to domain names.

"""
from __future__ import absolute_import

from django.conf import settings
from django.db import models, transaction
from django.utils.translation import gettext as _
from model_utils.models import TimeStampedModel


class DomainBase(TimeStampedModel):
    """
    This is the base model for domains.

    """

    domain = models.CharField(_("domain name"), max_length=255, unique=True)
    customer = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        verbose_name=_("customer"),
        blank=True,
        null=True,
        on_delete=models.CASCADE,
    )

    class Meta:
        abstract = True


class MailDomain(DomainBase):
    """
    This is the model for mail domains. Mail domains are used to configure the
    mail servers (SMTP/IMAP/POP3). Mail addresses are assigned to these mail
    domains.

    """

    class Meta(DomainBase.Meta):
        verbose_name = _("Mail domain")
        verbose_name_plural = _("Mail domains")

    def __str__(self):
        return self.domain

    def get_mailaddresses(self):
        """
        Get a list of mail addresses assigned to this mail domain.

        """
        return self.mailaddress_set.all()

    mailaddresses = property(get_mailaddresses)


class HostingDomainManager(models.Manager):
    """
    Default Manager for :py:class:`HostingDomain`.

    """

    @transaction.atomic
    def create_for_hosting_package(self, hosting_package, domain, commit, **kwargs):
        from hostingpackages.models import CustomerHostingPackageDomain

        hostingdomain = self.create(
            customer=hosting_package.customer, domain=domain, **kwargs
        )
        hostingdomain.maildomain = MailDomain.objects.create(
            customer=hosting_package.customer, domain=domain
        )
        custdomain = CustomerHostingPackageDomain.objects.create(
            hosting_package=hosting_package, domain=hostingdomain
        )
        if commit:
            hostingdomain.save()
            custdomain.save()
        return hostingdomain


class HostingDomain(DomainBase):
    """
    This is the model for hosting domains. A hosting domain is linked to a
    customer hosting account.

    """

    maildomain = models.OneToOneField(
        MailDomain,
        verbose_name=_("mail domain"),
        blank=True,
        null=True,
        help_text=_("assigned mail domain for this domain"),
        on_delete=models.CASCADE,
    )

    objects = HostingDomainManager()

    class Meta:
        verbose_name = _("Hosting domain")
        verbose_name_plural = _("Hosting domains")

    def __str__(self):
        return self.domain
