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.select_by_content_object(self.vcpe.instance).filter(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)

