from django.db import models
from django.contrib import admin
from django.contrib.auth.models import User as DjangoUser

DOMAIN_TRANSPORT_CHOICES = (
    ('virtual:', 'Virtual Domain'),
    ('mailman:', 'Mailman-managed Domain'),
)

DEFAULT_QUOTA = 0;
DEFAULT_MAXMAILBOX = 0;

class UserProfile(models.Model):
    """
    Defines the domains for which the user is an admin
    """
    admin_for = models.ManyToManyField('Domain')
    user = models.ForeignKey(DjangoUser, unique=True)

    def __unicode__(self):
        return self.user.username


class ConfigScheme(models.Model):
    """
    Defines a Scheme for UID, GID, Maildir of Domains
    """
    name = models.CharField('ConfigScheme Name', max_length=200)
    owner = models.ForeignKey(DjangoUser)
    maildirprefix = models.CharField('Maildir Prefix', max_length=300)
    uid = models.IntegerField('vMail UID')
    gid = models.IntegerField('vMail GID')

    def __unicode__(self):
        return self.name


class Domain(models.Model):
    """
    The FQDNs known to our System
    """
    name = models.CharField(max_length=255, help_text="Fully Qualified Domain Name (FQDN)")
    owner = models.ForeignKey(DjangoUser)
    maxmailboxes = models.IntegerField('Max Mailboxes',default=DEFAULT_MAXMAILBOX)
    maxquota = models.IntegerField('Max. Quota',default=DEFAULT_QUOTA)
    created_date = models.DateTimeField('Created At',editable=True,auto_now_add=True)
    enabled = models.BooleanField('Enabled',default=True)
    transport = models.CharField(max_length=128, choices=DOMAIN_TRANSPORT_CHOICES, help_text="Use Virtual Domain for most domains")
    configscheme = models.ForeignKey(ConfigScheme)

    def __unicode__(self):
        return "%s" % (self.name)

    def __repr__(self):
        return "<domain %s:%s>" % (self.transport, self.name)

    class Meta:
        ordering = ['name']

class DomainOptions(admin.ModelAdmin):
    list_display = ('name', 'transport', 'owner', 'configscheme')
    list_filter = ('transport', 'owner', 'configscheme') # 'default_user')

class User(models.Model):
    """
    Every Mail-, XMPP-, POP3- or IMAP-User known to our System
    """
    address = models.CharField(max_length=255)
    domain = models.ForeignKey(Domain)
    enabled = models.BooleanField('Enabled',default=True)
    password = models.CharField(max_length=255, help_text="crypt()ed version of the password", blank=True)
    passwordclear = models.CharField('ClearText Password', max_length=200,blank=True)
    realname = models.CharField(max_length=255, blank=True, null=True)
    alternative_mail = models.EmailField(blank=True, null=True)
    maxquota = models.IntegerField('Quota',editable=True,default=0)
    created_date = models.DateTimeField('Created At',auto_now_add=True,editable=True)
    changed = models.IntegerField('Changed',null=True,editable=False,default=0)
    smtp = models.BooleanField('SMTP', default=True, help_text="Allow incoming Email and SMTP Authentification")
    imap = models.BooleanField('IMAP', default=True, help_text="Allow IMAP4 access")
    pop3 = models.BooleanField('POP3', default=True, help_text="Allow POP3 access")
    xmpp = models.BooleanField('XMPP', default=False, help_text="Allow XMPP/Jabber access. This allows the user to change the password themselves")

    def save(self):
        # create hashed password
        from crypt import crypt
        from random import getrandbits
        if len(self.passwordclear)>0:
            self.password = crypt(self.passwordclear, "%s" % getrandbits(16));
        self.passwordclear = ''
        super(User, self).save();

    def __unicode__(self):
        return "%s@%s" % (self.address, self.domain.name)

class UserOptions(admin.ModelAdmin):
    list_display = ('__unicode__', 'enabled', 'smtp', 'imap', 'pop3', 'xmpp', 'maxquota')
    list_filter = ('domain', 'enabled', 'smtp', 'imap', 'pop3', 'xmpp', 'created_date') 
#    list_filter = ('domain', 'enabled', 'smtp', 'imap', 'pop3', 'xmpp', 'maxquota', 'created_date')
    search_fields = ['address', 'realname']
    fieldsets = (
        (None, {
            'fields': (('address', 'domain', 'enabled'),
                'password', 'passwordclear', 'realname', 'alternative_mail')
            }),
        ('Permissions', {
            'fields': ('smtp', 'imap', 'pop3', 'xmpp')
            }),
        (None, {
        'fields': ('maxquota',)
    }))
    save_on_top = True

class Recipient(models.Model):
    full_address = models.EmailField(unique=True)
    comment = models.CharField(max_length=255, blank=True, null=True)

    def __unicode__(self):
        return self.full_address

    class Meta:
        ordering = ('full_address',)

class Alias(models.Model):
    """
    Email Forwardings in the System
    """
    address = models.CharField(max_length=255, blank=True, null=True)
    domain = models.ForeignKey(Domain)
    enabled = models.BooleanField('Enabled',default=True)
    recipients = models.ManyToManyField(Recipient)#, filter_interface=models.HORIZONTAL)

    def __unicode__(self):
        return "%s@%s" % (self.address, self.domain.name)

    class Meta:
        ordering = ('domain', 'address')
        verbose_name_plural = 'Aliases'

class AliasOptions(admin.ModelAdmin):
    # if you put __unicode__ in there, you need domain too -
    # because of http://code.djangoproject.com/ticket/3740
    # and http://code.djangoproject.com/ticket/2076
    # (in short, __unicode__ of self requires lookup of 
    #  mail_domain.name in db, but django ORM messes up) 
    list_display = ('__unicode__', 'domain', 'enabled') 
    list_filter = ('domain', 'enabled')
    ordering = ('domain', 'address')

admin.site.register(UserProfile)
admin.site.register(ConfigScheme)
admin.site.register(Domain, DomainOptions)
admin.site.register(User, UserOptions)
admin.site.register(Recipient)
admin.site.register(Alias, AliasOptions)

