#(c) Roland van Laar 2006
# vi:et:ts=4
from django.db import models

#No need to formalize it; CHOICES don't change much

STATUS_CHOICES = ( 
         ('up', 'up'),
         ('dw', 'down'),
         ('pl', 'planned'),
         )

POLAR_CHOICES = (
         ('hr', 'horizontal'),
         ('vr', 'vertical'),
         )

INTERFACE_TYPE_CHOICES = (
         ('eth', 'eth'),
         ('11a', '11a'),
         ('11b', '11b'),
         ('11g', '11g'),
         )
WIFI_MODE_CHOICES = (
         ('ms', 'master'),
         ('mn', 'managed'),
         )

class Antenna(models.Model):
    type = models.CharField(max_length=20, unique=True)
    gain = models.IntegerField(max_length=3)

    class Meta:
        verbose_name = 'Antenna'

    def __unicode__(self):
        return self.type

class Location(models.Model):
    description = models.CharField(max_length=200, unique=True)
    longitude = models.DecimalField(max_digits=8,decimal_places=6)
    latitude = models.DecimalField(max_digits=8,decimal_places=6)

    class Meta:
        verbose_name = 'Location'

    def __unicode__(self):
        return self.description


#XXX: Name Domain perhaps?
class DnsServer(models.Model):
    ipaddress = models.IPAddressField()
    domainname = models.CharField(max_length=50, unique=True)
    
    class Meta:
        verbose_name = 'Dns Server'
    
    def __unicode__(self):
        return "%s, %s"% (self.domainname, self.ipaddress )

class Network(models.Model):
    name = models.CharField(max_length=50, unique=True)
    ipspacestart = models.IPAddressField()
    netmask = models.IntegerField()

    class Meta:
     verbose_name = 'Network'

    def __unicode__(self):
        return self.name

class Node(models.Model):
    name = models.CharField(max_length=30, unique=True)
    location = models.ForeignKey(Location)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES , \
        default='up')
    network = models.ForeignKey(Network,default=1)
    masterip = models.IPAddressField(unique=True)
 
    class Meta:
        ordering = ['name']
        verbose_name = 'Node'

    def __unicode__(self):
        return self.name

   # def save(self, force_insert=False, force_update=False):
   #     #XXX: could there be racing conditions?
   #     #XXX: Maybe move this to a model form, 
   #     from wllogic import free_master_ip
   #     # check if there is a masterip, if not generate one.
   #     # check if there is a network change, if so, generate a new masterip.
   #     if self.masterip:
   #         old = Node.objects.get(pk=self.pk)
   #         if old.network != self.network:
   #             self.masterip = free_master_ip(self.network)
   #     else:
   #         self.masterip = free_master_ip(self.network)
   #     super(Node, self).save(force_insert, force_update)

class Interface(models.Model):
    node = models.ForeignKey(Node)
    type = models.CharField(max_length=10, choices=INTERFACE_TYPE_CHOICES, 
            default='eth')
    iface = models.CharField(max_length=10, verbose_name="interface", 
            default='eth0')
    ip = models.IPAddressField(unique=True, blank=True)
    netmask = models.IntegerField(default=30)
    polar = models.CharField(blank=True, max_length=10, choices=POLAR_CHOICES)
    ssid = models.CharField(max_length=50, blank=True, null=True)
    mode = models.CharField(max_length=10, choices=WIFI_MODE_CHOICES,
            blank=True)
    channel = models.IntegerField(blank=True, null=True)
    antenna = models.ForeignKey(Antenna, blank=True, null=True)
    shortdesc = models.CharField(blank=True, max_length=10)
    desc = models.CharField(blank=True, max_length=100)
    accesspoint = models.BooleanField()
    link = models.ForeignKey('self', blank=True, null=True)
   
    class Meta:
        #unique_together = ('node', 'iface')
        verbose_name = 'Interface'
   
    def __unicode__(self):
        return "%s/%s" % (self.node, self.iface)

#
# XXX: Currently not used, require rethinking wether we _really_ still needs
# this feature as we going to use a new interlink IP naming model
class InterfaceAlias(models.Model):
    iface = models.ForeignKey(Interface,related_name='child')
    ip = models.IPAddressField(unique=True)
    netmask = models.IntegerField(default=30)
    shortdesc = models.CharField(blank=True, max_length=10)
    desc = models.CharField(blank=True, max_length=100)
    linkAlias = models.ForeignKey('self', blank=True, null=True)
    link = models.ForeignKey(Interface, blank=True, null=True)
   
    def __unicode__(self):
        return "Alias %s" % (self.iface)

#
# XXX: Needs rethinking, dhcp[start|stop] could be removed if whole publicAP is
# going to be activated as DHCP range, or only number of fixed clients needs to
# be defined, all other could be calculated on the fly if needed

#class PublicAP(models.Model):
#     iface = models.ForeignKey(Interface,related_name='ap', verbose_name="interface")
#     ip = models.IPAddressField(unique=True)
#     netmask = models.IntegerField(default=28)
#     dhcpstart = models.IPAddressField()
#     dhcpstop = models.IPAddressField()
#     shortdesc = models.CharField(max_length=10)
#     desc = models.CharField(max_length=100)
#
#     class Meta:
#         verbose_name = "Public Access Point"
#
#     def __unicode__(self):
#         return "%s:%s" % (self.iface,self.pk)

class DhcpStatic(models.Model):
    hostname = models.CharField(max_length=10,unique=True)
    macaddress = models.CharField(max_length=17)
    address = models.IPAddressField()
    PublicAP = models.ForeignKey(Interface)

    class Meta:
        verbose_name = "Static host"

    def __unicode__(self):
        return self.hostname
