def __init__(self, *args, **kwargs):
    volt_services = VOLTService.objects.all()
    if volt_services:
        self._meta.get_field("provider_service").default = volt_services[0].id
    super(VOLTTenant, self).__init__(*args, **kwargs)
    self.cached_vcpe = None

@property
def vcpe(self):
    from services.vsg.models import VSGTenant
    vcpe = self.get_newest_subscribed_tenant(VSGTenant)
    if not vcpe:
        return None

    # always return the same object when possible
    if (self.cached_vcpe) and (self.cached_vcpe.id == vcpe.id):
        return self.cached_vcpe

    vcpe.caller = self.creator
    self.cached_vcpe = vcpe
    return vcpe

@vcpe.setter
def vcpe(self, value):
    raise XOSConfigurationError("vOLT.vCPE cannot be set this way -- create a new vCPE object and set its subscriber_tenant instead")

@property
def subscriber(self):
    if not self.subscriber_root:
        return None
    subs = CordSubscriberRoot.objects.filter(id=self.subscriber_root.id)
    if not subs:
        return None
    return subs[0]

def manage_vcpe(self):
    # Each VOLT object owns exactly one VCPE object

    if self.deleted:
        return

    # Check to see if the wrong s-tag is set. This can only happen if the
    # user changed the s-tag after the VoltTenant object was created.
    if self.vcpe and self.vcpe.instance:
        s_tags = Tag.objects.filter(content_type=self.vcpe.instance.get_content_type_key(), object_id=self.vcpe.instance.id, name="s_tag")
        if s_tags and (s_tags[0].value != str(self.s_tag)):
            self.vcpe.delete()

    if self.vcpe is None:
        from services.vsg.models import VSGService, VSGTenant
        vsgServices = VSGService.objects.all()
        if not vsgServices:
            raise XOSConfigurationError("No VSG Services available")

        vcpe = VSGTenant(provider_service = vsgServices[0],
                          subscriber_tenant = self)
        vcpe.caller = self.creator
        vcpe.save()

def manage_subscriber(self):
    if (self.subscriber_root is None):
        # The vOLT is not connected to a Subscriber, so either find an
        # existing subscriber with the same SSID, or autogenerate a new
        # subscriber.
        #
        # TODO: This probably goes away when we rethink the ONOS-to-XOS
        # vOLT API.

        subs = CordSubscriberRoot.objects.filter(service_specific_id = self.service_specific_id)
        if subs:
            sub = subs[0]
        else:
            sub = CordSubscriberRoot(service_specific_id = self.service_specific_id,
                                     name = "autogenerated-for-vOLT-%s" % self.id)
            sub.save()
        self.subscriber_root = sub
        self.save()

def cleanup_vcpe(self):
    if self.vcpe:
        # print "XXX cleanup vcpe", self.vcpe
        self.vcpe.delete()

def cleanup_orphans(self):
    from services.vsg.models import VSGTenant
    # ensure vOLT only has one vCPE
    cur_vcpe = self.vcpe
    for vcpe in list(self.get_subscribed_tenants(VSGTenant)):
        if (not cur_vcpe) or (vcpe.id != cur_vcpe.id):
            # print "XXX clean up orphaned vcpe", vcpe
            vcpe.delete()

def save(self, *args, **kwargs):
    # VOLTTenant probably doesn't need a SSID anymore; that will be handled
    # by CORDSubscriberRoot...
    # self.validate_unique_service_specific_id()

    if (self.subscriber_root is not None):
        subs = self.subscriber_root.get_subscribed_tenants(VOLTTenant)
        if (subs) and (self not in subs):
            raise XOSDuplicateKey("Subscriber should only be linked to one vOLT")

    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("VOLTTenant's self.caller was not set")
        self.creator = self.caller
        if not self.creator:
            raise XOSProgrammingError("VOLTTenant's self.creator was not set")

    super(VOLTTenant, self).save(*args, **kwargs)
    model_policy_volt(self.pk)

def delete(self, *args, **kwargs):
    self.cleanup_vcpe()
    super(VOLTTenant, self).delete(*args, **kwargs)

