
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from synchronizers.new_base.modelaccessor import VOLTServiceInstance, ServiceInstanceLink, ONUDevice, ServiceInstance, model_accessor
from synchronizers.new_base.policy import Policy

class VOLTServiceInstancePolicy(Policy):
    model_name = "VOLTServiceInstance"

    def handle_create(self, si):
        return self.handle_update(si)

    def handle_update(self, si):

        if (si.link_deleted_count > 0) and (not si.provided_links.exists()):
            # If this instance has no links pointing to it, delete
            self.handle_delete(si)
            if VOLTServiceInstance.objects.filter(id=si.id).exists():
                si.delete()
            return

        self.create_eastbound_instance(si)
        self.associate_onu_device(si)

    def handle_delete(self, si):
        pass

    def create_eastbound_instance(self, si):
        links = si.owner.subscribed_dependencies.all()
        for link in links:
            # SEBA-216 prevent any attempt to create an ONOSServiceInstance
            if "onos" in link.provider_service.name.lower():
                continue

            provider_service = link.provider_service.leaf_model

            valid_provider_service_instance = provider_service.validate_links(si)
            if not valid_provider_service_instance:
                provider_service.acquire_service_instance(si)

    def associate_onu_device(self, si):

        self.logger.debug("MODEL_POLICY: attaching ONUDevice to VOLTServiceInstance %s" % si.id)

        base_si = ServiceInstance.objects.get(id=si.id)
        try:
            onu_device_serial_number = base_si.get_westbound_service_instance_properties("onu_device")
        except Exception as e:
            raise Exception(
                "VOLTServiceInstance %s has no westbound ServiceInstance specifying the onu_device, you need to manually specify it" % self.id)

        try:
            onu = ONUDevice.objects.get(serial_number=onu_device_serial_number)
        except IndexError:
            raise Exception("ONUDevice with serial number %s can't be found" % onu_device_serial_number)

        si.onu_device_id = onu.id
        si.save()
