from core.models.plcorebase import *
from models_decl import VBBUService_decl
from models_decl import VBBUVendor_decl
from models_decl import VBBUTenant_decl

from django.db import models
from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, NetworkParameter, NetworkParameterType, Port, AddressPool
from core.models.plcorebase import StrippedCharField
import os
from django.db import models, transaction
from django.forms.models import model_to_dict
from django.db.models import *
from operator import itemgetter, attrgetter, methodcaller
from core.models import Tag
from core.models.service import LeastLoadedNodeScheduler
import traceback
from xos.exceptions import *
from xos.config import Config

class VBBUService(VBBUService_decl):
   class Meta:
        proxy = True 

   def create_tenant(self, **kwargs):
       t = VBBUTenant(kind="vRAN", provider_service=self, connect_method="na", **kwargs)
       t.save()
       return t

class VBBUVendor(VBBUVendor_decl):
   class Meta:
        proxy = True 

class VBBUTenant(VBBUTenant_decl):
   class Meta:
        proxy = True 

   def __init__(self, *args, **kwargs):
       vbbuservice = VBBUService.get_service_objects().all()
       if vbbuservice:
           self._meta.get_field(
                   "provider_service").default = vbbuservice[0].id
       super(VBBUTenant, self).__init__(*args, **kwargs)

   @property
   def image(self):
       if not self.vbbu_vendor:
           return super(VBBUTenant, self).image
       return self.vbbu_vendor.image
   
   def save_instance(self, instance):
       if self.vbbu_vendor:
           instance.flavor = self.vbbu_vendor.flavor
       super(VBBUTenant, self).save_instance(instance)

   def save(self, *args, **kwargs):
       if not self.creator:
           if not getattr(self, "caller", None):
               raise XOSProgrammingError("VBBUTenant's self.caller was not set")
           self.creator = self.caller
           if not self.creator:
               raise XOSProgrammingError("VBBUTenant's self.creator was not set")

       super(VBBUTenant, self).save(*args, **kwargs)
       # This call needs to happen so that an instance is created for this
       # tenant is created in the slice. One instance is created per tenant.
       model_policy_vbbutenant(self.pk)

   def delete(self, *args, **kwargs):
       # Delete the instance that was created for this tenant
       self.cleanup_container()
       super(VBBUTenant, self).delete(*args, **kwargs)

def model_policy_vbbutenant(pk):
    # This section of code is atomic to prevent race conditions
    with transaction.atomic():
        # We find all of the tenants that are waiting to update
        tenant = VBBUTenant.objects.select_for_update().filter(pk=pk)
        if not tenant:
            return
        # Since this code is atomic it is safe to always use the first tenant
        tenant = tenant[0]
        tenant.manage_container()
