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


#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_masterip
   #     # 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_masterip(self.network)
   #     else:
   #         self.masterip = free_masterip(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=30, 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)
	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)

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(PublicAP)

    class Meta:
        verbose_name = "Static host"

    def __unicode__(self):
        return self.hostname
