import os
import datetime
from django.db import models
from plstackapi.openstack.driver import OpenStackDriver

# Create your models here.

class PlCoreBase(models.Model):

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    def save(self):
        if not self.id:
            self.created = datetime.date.today()
        self.updated = datetime.datetime.today()
        super(PlCoreBase, self).save()

class Role(PlCoreBase):

    ROLE_CHOICES = (('admin', 'Admin'), ('pi', 'Principle Investigator'), ('user','User'))
    role_id = models.CharField(max_length=256, unique=True)
    role_type = models.CharField(max_length=80, unique=True, choices=ROLE_CHOICES)

    def __unicode__(self):  return u'%s' % (self.role_type)

    def save(self):
        if not self.id:
            self.created = datetime.date.today()
        self.updated = datetime.datetime.today()
        super(Role, self).save()

class Site(PlCoreBase):
    tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id")
    name = models.CharField(max_length=200, help_text="Name for this Site")
    site_url = models.URLField(null=True, blank=True, max_length=512, help_text="Site's Home URL Page")
    enabled = models.BooleanField(default=True, help_text="Status for this Site")
    longitude = models.FloatField(null=True, blank=True)
    latitude = models.FloatField(null=True, blank=True)
    login_base = models.CharField(max_length=50, help_text="Prefix for Slices associated with this Site")
    is_public = models.BooleanField(default=True, help_text="Indicates the visibility of this site to other members")
    abbreviated_name = models.CharField(max_length=80)

    def __unicode__(self):  return u'%s' % (self.name)


class User(PlCoreBase):
    user_id = models.CharField(max_length=256, unique=True)
    firstname = models.CharField(help_text="person's given name", max_length=200)
    lastname = models.CharField(help_text="person's surname", max_length=200)
    email = models.EmailField(help_text="e-mail address")
    phone = models.CharField(null=True, blank=True, help_text="phone number contact", max_length=100)
    user_url = models.URLField(null=True, blank=True)
    is_admin = models.BooleanField(default=False)
    site = models.ForeignKey(Site, verbose_name="Site this user will be homed too")

    def __unicode__(self):  return u'%s' % (self.email)

    def save(self, *args, **kwds):
        driver  = OpenStackDriver()
        name = self.email[:self.email.find('@')]
        fields = {'name': name, 'email': self.email, 'password': self.password,
                  'enabled': self.enabled}
        if not self.id:
            user = driver.create_user(**fields) 
        else:
            driver.update_user(self.user_id, **fields)
        super(User, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        driver = OpenStackDriver()
        driver.delete_user(self.user_id)
        super(User, self).delete(*args, **kwds)

class SitePrivilege(PlCoreBase):

    user = models.ForeignKey('User')
    site = models.ForeignKey('Site')
    role = models.ForeignKey('Role')

    def __unicode__(self):  return u'%s %s %s' % (self.site, self.user, self.role)

    def save(self, *args, **kwds):
        driver  = OpenStackDriver()
        driver.add_user_role(user_id=user.user_id, 
                             tenant_id=site.tenant_id, 
                             role_name=role.name)
        super(SitePrivilege, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        driver = OpenStackDriver()
        driver.delete_user_role(user_id=user.user_id,
                                tenant_id=site.tenant_id,
                                role_name=role.name)
        super(SitePrivilege, self).delete(*args, **kwds)
         

class DeploymentNetwork(PlCoreBase):
    name = models.CharField(max_length=200, unique=True, help_text="Name of the Deployment Network")

    def __unicode__(self):  return u'%s' % (self.name)

class SiteDeploymentNetwork(PlCoreBase):
    class Meta:
        unique_together = ['site', 'deploymentNetwork']

    site = models.ForeignKey(Site)
    deploymentNetwork = models.ForeignKey(DeploymentNetwork)
    name = models.CharField(default="Blah", max_length=100)


    def __unicode__(self):  return u'%s::%s' % (self.site, self.deploymentNetwork)


class Slice(PlCoreBase):
    tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id")
    name = models.CharField(help_text="The Name of the Slice", max_length=80)
    enabled = models.BooleanField(default=True, help_text="Status for this Slice")
    SLICE_CHOICES = (('plc', 'PLC'), ('delegated', 'Delegated'), ('controller','Controller'), ('none','None'))
    instantiation = models.CharField(help_text="The instantiation type of the slice", max_length=80, choices=SLICE_CHOICES)
    omf_friendly = models.BooleanField()
    description=models.TextField(blank=True,help_text="High level description of the slice and expected activities", max_length=1024)
    slice_url = models.URLField(blank=True, max_length=512)
    site = models.ForeignKey(Site, help_text="The Site this Node belongs too")
    network_id = models.CharField(max_length=256, help_text="Quantum network")
    router_id = models.CharField(max_length=256, help_text="Quantum router id")

    def __unicode__(self):  return u'%s' % (self.name)

    def save(self, *args, **kwds):
        # sync keystone tenant
        driver  = OpenStackDriver()

        if not self.id:
            tenant = driver.create_tenant(tenant_name=self.name,
                                          description=self.description,
                                          enabled=self.enabled)
            self.tenant_id = tenant.id
            
            # create a network  
            network = driver.create_network(name=self.name)
            self.network_id = network['id']        
            # create router
            router = driver.create_router(name=self.name)
            self.router_id = router['id']     

        else:
            # update record
            self.driver.update_tenant(self.tenant_id, name=self.name,
                                      description=self.description, enabled=self.enabled)
        super(Slice, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        # delete keystone tenant
        driver  = OpenStackDriver()
        driver.delete_tenant(self.tenant_id)
        super(Slice, self).delete(*args, **kwds)

class SliceMembership(PlCoreBase):
    user = models.ForeignKey('User')
    slice = models.ForeignKey('Slice')
    role = models.ForeignKey('Role')

    def __unicode__(self):  return u'%s %s %s' % (self.slice, self.user, self.role)

    def save(self, *args, **kwds):
        driver  = OpenStackDriver()
        driver.add_user_role(user_id=user.user_id,
                             tenant_id=slice.tenant_id,
                             role_name=role.name)
        super(SliceMembership, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        driver = OpenStackDriver()
        driver.delete_user_role(user_id=user.user_id,
                                tenant_id=slice.tenant_id,
                                role_name=role.name)
        super(SliceMembership, self).delete(*args, **kwds)

class SubNet(PlCoreBase):
    subnet_id = models.CharField(max_length=256, unique=True)
    cidr = models.CharField(max_length=20)
    ip_version = models.IntegerField()
    start = models.IPAddressField()
    end = models.IPAddressField()
    slice = models.ForeignKey(Slice )

    def __unicode__(self):  return u'%s' % (self.name)

    def save(self, *args, **kwargs):
        driver  = OpenStackDriver()
        if not self.id:
            subnet = driver.create_subnet(network_name=self.slice.name,
                                          cidr_ip = self.cidr,
                                          ip_version=self.ip_version,
                                          start = self.start,
                                          end = self.end)

            self.subnet_id = subnet.id

        # add subnet as interface to slice router
        driver.add_router_interface(self.slice.router_id, subnet.id)

        super(SubNet, self).save(*args, **kwargs)


    def delete(self, *args, **kwargs):
        # delete quantum network
        driver  = OpenStackDriver()
        driver.delete_subnet(self.subnet_id)
        driver.delete_router_interface(self.slice.router_id, self.subnet.id)
        super(SubNet, self).delete(*args, **kwargs)

class Node(PlCoreBase):
    name = models.CharField(max_length=200, unique=True, help_text="Name of the Node")
    siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork, help_text="The Site and Deployment Network this Node belongs too.")

    def __unicode__(self):  return u'%s' % (self.name)

class Image(PlCoreBase):
    image_id = models.CharField(max_length=256, unique=True)
    name = models.CharField(max_length=256, unique=True)
    disk_format = models.CharField(max_length=256)
    container_format = models.CharField(max_length=256)

    def __unicode__(self):  return u'%s' % (self.name)


class Flavor(PlCoreBase):
    flavor_id = models.IntegerField(unique=True)
    name = models.CharField(max_length=256, unique=True)
    memory_mb = models.IntegerField()
    disk_gb = models.IntegerField()
    vcpus = models.IntegerField()

    def __unicode__(self):  return u'%s' % (self.name)

class Key(PlCoreBase):
    name = models.CharField(max_length=256, unique=True)
    key = models.CharField(max_length=512)
    type = models.CharField(max_length=256)
    blacklisted = models.BooleanField()
    user = models.ForeignKey(User)

    def __unicode__(self):  return u'%s' % (self.name)

    def save(self, *args, **kwds):
        driver  = OpenStackDriver()
        if not self.id:
            keypair = driver.create_keypair(name=self.name, key=self.key)
        super(Key, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        driver  = OpenStackDriver()
        driver.delete_keypair(self.name)
        super(Key, self).delete(*args, **kwds)



class Sliver(PlCoreBase):
    instance_id = models.CharField(max_length=200, help_text="Nova instance id")    
    name = models.CharField(max_length=200, help_text="Sliver name")
    flavor = models.ForeignKey(Flavor)
    image = models.ForeignKey(Image) 
    key = models.ForeignKey(Key)        
    slice = models.ForeignKey(Slice)
    siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork)
    node = models.ForeignKey(Node)

    def __unicode__(self):  return u'%s::%s' % (self.slice, self.siteDeploymentNetwork)

    def save(self, *args, **kwds):
        driver  = OpenStackDriver()
        instance = driver.spawn_instances(name=self.name,
                                          keyname=self.name,
                                          hostnames=self.node.name,
                                          flavor=self.flavor.name,
                                          image=self.image.name)
        self.instance_id = instance.id
        super(Sliver, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        driver  = OpenStackDriver()
        driver.destroy_instance(name=self.name, id=self.instance_id)
        super(Sliver, self).delete(*args, **kwds)

