from header import *



#from core.models.service import Service
from core.models import Service



#from core.models.tenantwithcontainer import TenantWithContainer
from core.models import TenantWithContainer





class VSGService(Service):

  KIND = "vCPE"

  class Meta:
      app_label = "vsg"
      name = "vsg"
      verbose_name = "vSG Service"

  # Primitive Fields (Not Relations)
  url_filter_kind = StrippedCharField( blank = True, max_length = 30, null = True, db_index = False, choices = ((None, 'None'), ('safebrowsing', 'Safe Browsing'), ('answerx', 'AnswerX')) )
  dns_servers = StrippedCharField( default = "8.8.8.8", max_length = 255, null = False, db_index = False, blank = False )
  node_label = StrippedCharField( db_index = False, max_length = 30, null = True, blank = True )
  docker_image_name = StrippedCharField( default = "docker.io/xosproject/vsg", max_length = 255, null = False, db_index = False, blank = False )
  docker_insecure_registry = BooleanField( default = False, null = False, blank = True, db_index = False )
  

  # Relations
  

  
  pass




class VSGTenant(TenantWithContainer):

  KIND = "vCPE"

  class Meta:
      app_label = "vsg"
      name = "vsg"
      verbose_name = "vSG Service"

  # Primitive Fields (Not Relations)
  last_ansible_hash = StrippedCharField( db_index = False, max_length = 128, null = True, blank = True )
  

  # Relations
  

  sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
                     "wan_container_gateway_ip", "wan_container_gateway_mac",
                     "wan_vm_ip", "wan_vm_mac")
  
  def __init__(self, *args, **kwargs):
      super(VSGTenant, self).__init__(*args, **kwargs)
      self.cached_vrouter=None
  
  @property
  def vrouter(self):
      vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
      if not vrouter:
          return None
  
      # always return the same object when possible
      if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
          return self.cached_vrouter
  
      vrouter.caller = self.creator
      self.cached_vrouter = vrouter
      return vrouter
  
  @vrouter.setter
  def vrouter(self, value):
      raise XOSConfigurationError("VSGTenant.vrouter setter is not implemented")
  
  @property
  def volt(self):
      from services.volt.models import VOLTTenant
      if not self.subscriber_tenant:
          return None
      volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
      if not volts:
          return None
      return volts[0]
  
  @volt.setter
  def volt(self, value):
      raise XOSConfigurationError("VSGTenant.volt setter is not implemented")
  
  @property
  def ssh_command(self):
      if self.instance:
          return self.instance.get_ssh_command()
      else:
          return "no-instance"
  
  def get_vrouter_field(self, name, default=None):
      if self.vrouter:
          return getattr(self.vrouter, name, default)
      else:
          return default
  
  @property
  def wan_container_ip(self):
      return self.get_vrouter_field("public_ip", None)
  
  @property
  def wan_container_mac(self):
      return self.get_vrouter_field("public_mac", None)
  
  @property
  def wan_container_netbits(self):
      return self.get_vrouter_field("netbits", None)
  
  @property
  def wan_container_gateway_ip(self):
      return self.get_vrouter_field("gateway_ip", None)
  
  @property
  def wan_container_gateway_mac(self):
      return self.get_vrouter_field("gateway_mac", None)
  
  @property
  def wan_vm_ip(self):
      tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
      if tags:
          tenant = VRouterTenant.objects.get(id=tags[0].value)
          return tenant.public_ip
      else:
          raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
  
  @property
  def wan_vm_mac(self):
      tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
      if tags:
          tenant = VRouterTenant.objects.get(id=tags[0].value)
          return tenant.public_mac
      else:
          raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
  
  @property
  def is_synced(self):
      return (self.enacted is not None) and (self.enacted >= self.updated)
  
  @is_synced.setter
  def is_synced(self, value):
      pass
  
  def get_vrouter_service(self):
      vrouterServices = VRouterService.get_service_objects().all()
      if not vrouterServices:
          raise XOSConfigurationError("No VROUTER Services available")
      return vrouterServices[0]
  
  def manage_vrouter(self):
      # Each vCPE object owns exactly one vRouterTenant object
  
      if self.deleted:
          return
  
      if self.vrouter is None:
          vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_tenant = self)
          vrouter.caller = self.creator
          vrouter.save()
  
  def cleanup_vrouter(self):
      if self.vrouter:
          # print "XXX cleanup vrouter", self.vrouter
          self.vrouter.delete()
  
  def cleanup_orphans(self):
      # ensure vCPE only has one vRouter
      cur_vrouter = self.vrouter
      for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
          if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
              # print "XXX clean up orphaned vrouter", vrouter
              vrouter.delete()
  
      if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
          instances=Instance.objects.filter(id=self.orig_instance_id)
          if instances:
              # print "XXX clean up orphaned instance", instances[0]
              instances[0].delete()
  
  def get_slice(self):
      if not self.provider_service.slices.count():
          print self, "dio porco"
          raise XOSConfigurationError("The service has no slices")
      slice = self.provider_service.slices.all()[0]
      return slice
  
  def get_vsg_service(self):
      return VSGService.get_service_objects().get(id=self.provider_service.id)
  
  def find_instance_for_s_tag(self, s_tag):
      #s_tags = STagBlock.objects.find(s_s_tag)
      #if s_tags:
      #    return s_tags[0].instance
  
      tags = Tag.objects.filter(name="s_tag", value=s_tag)
      if tags:
          return tags[0].content_object
  
      return None
  
  def find_or_make_instance_for_s_tag(self, s_tag):
      instance = self.find_instance_for_s_tag(self.volt.s_tag)
      if instance:
          return instance
  
      flavors = Flavor.objects.filter(name="m1.small")
      if not flavors:
          raise XOSConfigurationError("No m1.small flavor")
  
      slice = self.provider_service.slices.all()[0]
  
      if slice.default_isolation == "container_vm":
          (node, parent) = ContainerVmScheduler(slice).pick()
      else:
          (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_vsg_service().node_label).pick()
  
      instance = Instance(slice = slice,
                      node = node,
                      image = self.image,
                      creator = self.creator,
                      deployment = node.site_deployment.deployment,
                      flavor = flavors[0],
                      isolation = slice.default_isolation,
                      parent = parent)
  
      self.save_instance(instance)
  
      return instance
  
  def manage_container(self):
      from core.models import Instance, Flavor
  
      if self.deleted:
          return
  
      # For container or container_vm isolation, use what TenantWithCotnainer
      # provides us
      slice = self.get_slice()
      if slice.default_isolation in ["container_vm", "container"]:
          super(VSGTenant,self).manage_container()
          return
  
      if not self.volt:
          raise XOSConfigurationError("This vCPE container has no volt")
  
      if self.instance:
          # We're good.
          return
  
      instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
      self.instance = instance
      super(TenantWithContainer, self).save()
  
  def cleanup_container(self):
      if self.get_slice().default_isolation in ["container_vm", "container"]:
          super(VSGTenant,self).cleanup_container()
  
      # To-do: cleanup unused instances
      pass
  
  def find_or_make_port(self, instance, network, **kwargs):
      port = Port.objects.filter(instance=instance, network=network)
      if port:
          port = port[0]
      else:
          port = Port(instance=instance, network=network, **kwargs)
          port.save()
      return port
  
  def get_lan_network(self, instance):
      slice = self.provider_service.slices.all()[0]
      # there should only be one network private network, and its template should not be the management template
      lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
      if len(lan_networks)>1:
          raise XOSProgrammingError("The vSG slice should only have one non-management private network")
      if not lan_networks:
          raise XOSProgrammingError("No lan_network")
      return lan_networks[0]
  
  def save_instance(self, instance):
      with transaction.atomic():
          instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
          super(VSGTenant, self).save_instance(instance)
  
          if instance.isolation in ["container", "container_vm"]:
              lan_network = self.get_lan_network(instance)
              port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
              port.set_parameter("c_tag", self.volt.c_tag)
              port.set_parameter("s_tag", self.volt.s_tag)
              port.set_parameter("device", "eth1")
              port.set_parameter("bridge", "br-lan")
  
              wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
              if not wan_networks:
                  raise XOSProgrammingError("No wan_network")
              port = self.find_or_make_port(instance, wan_networks[0])
              port.set_parameter("next_hop", value="10.0.1.253")   # FIX ME
              port.set_parameter("device", "eth0")
  
          if instance.isolation in ["vm"]:
              lan_network = self.get_lan_network(instance)
              port = self.find_or_make_port(instance, lan_network)
              port.set_parameter("c_tag", self.volt.c_tag)
              port.set_parameter("s_tag", self.volt.s_tag)
              port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
              port.save()
  
          # tag the instance with the s-tag, so we can easily find the
          # instance later
          if self.volt and self.volt.s_tag:
              tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
              if not tags:
                  tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
                  tag.save()
  
          # VTN-CORD needs a WAN address for the VM, so that the VM can
          # be configured.
          tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
          if not tags:
              vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service)
              vrouter.set_attribute("tenant_for_instance_id", instance.id)
              vrouter.save()
              tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id)
              tag.save()
  
  def save(self, *args, **kwargs):
      if not self.creator:
          if not getattr(self, "caller", None):
              # caller must be set when creating a vCPE since it creates a slice
              raise XOSProgrammingError("VSGTenant's self.caller was not set")
          self.creator = self.caller
          if not self.creator:
              raise XOSProgrammingError("VSGTenant's self.creator was not set")
  
      super(VSGTenant, self).save(*args, **kwargs)
      model_policy_vcpe(self.pk)
  
  def delete(self, *args, **kwargs):
      self.cleanup_vrouter()
      self.cleanup_container()
      super(VSGTenant, self).delete(*args, **kwargs)
  
  pass

def model_policy_vcpe(pk):
    # TODO: this should be made in to a real model_policy
    with transaction.atomic():
        vcpe = VSGTenant.objects.select_for_update().filter(pk=pk)
        if not vcpe:
            return
        vcpe = vcpe[0]
        vcpe.manage_container()
        vcpe.manage_vrouter()
        vcpe.cleanup_orphans()


