
# 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.


import unittest
from mock import patch, call, Mock, PropertyMock

import os, sys

test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
service_dir=os.path.join(test_path, "../../../..")
xos_dir=os.path.join(test_path, "../../..")
if not os.path.exists(os.path.join(test_path, "new_base")):
    xos_dir=os.path.join(test_path, "../../../../../../orchestration/xos/xos")
    services_dir=os.path.join(xos_dir, "../../xos_services")

# While transitioning from static to dynamic load, the path to find neighboring xproto files has changed. So check
# both possible locations...
def get_models_fn(service_name, xproto_name):
    name = os.path.join(service_name, "xos", xproto_name)
    if os.path.exists(os.path.join(services_dir, name)):
        return name
    else:
        name = os.path.join(service_name, "xos", "synchronizer", "models", xproto_name)
        if os.path.exists(os.path.join(services_dir, name)):
            return name
    raise Exception("Unable to find service=%s xproto=%s" % (service_name, xproto_name))

class TestModelPolicyVOLTServiceInstance(unittest.TestCase):
    def setUp(self):
        global VOLTServiceInstancePolicy, MockObjectList

        self.sys_path_save = sys.path
        sys.path.append(xos_dir)
        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))

        config = os.path.join(test_path, "test_config.yaml")
        from xosconfig import Config
        Config.clear()
        Config.init(config, 'synchronizer-config-schema.yaml')

        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
        build_mock_modelaccessor(xos_dir, services_dir, [get_models_fn("olt-service", "volt.xproto"),
                                                         get_models_fn("vsg", "vsg.xproto"),
                                                         get_models_fn("../profiles/rcord", "rcord.xproto")])

        import synchronizers.new_base.modelaccessor
        import model_policy_voltserviceinstance
        from model_policy_voltserviceinstance import VOLTServiceInstancePolicy, model_accessor

        from mock_modelaccessor import MockObjectList

        # import all class names to globals
        for (k, v) in model_accessor.all_model_classes.items():
            globals()[k] = v

        # Some of the functions we call have side-effects. For example, creating a VSGServiceInstance may lead to creation of
        # tags. Ideally, this wouldn't happen, but it does. So make sure we reset the world.
        model_accessor.reset_all_object_stores()

        self.policy = VOLTServiceInstancePolicy()
        self.si = Mock()

    def tearDown(self):
        sys.path = self.sys_path_save

    def test_handle_create(self):
        with patch.object(VOLTServiceInstancePolicy, "create_eastbound_instance") as create_eastbound_instance, \
            patch.object(VOLTServiceInstancePolicy, "associate_onu_device") as associate_onu_device:

            self.policy.handle_create(self.si)
            create_eastbound_instance.assert_called_with(self.si)
            associate_onu_device.assert_called_with(self.si)

    def test_create_vsg(self):
        with patch.object(ServiceInstanceLink, "save", autospec=True) as save_link, \
            patch.object(VSGServiceInstance, "save", autospec=True) as save_vsg:

            link = Mock()
            link.provider_service.get_service_instance_class_name.return_value = "VSGServiceInstance"

            si = Mock()
            si.subscribed_links.all.return_value = []
            si.owner.subscribed_dependencies.all.return_value = [link]

            self.policy.create_eastbound_instance(si)

            # Should have created a vsg

            self.assertEqual(save_vsg.call_count, 1)
            vsg = save_vsg.call_args[0][0]

            # Should have created a link from OLT to vsg

            self.assertEqual(save_link.call_count, 1)
            link = save_link.call_args[0][0]
            self.assertEqual(link.provider_service_instance, vsg)
            self.assertEqual(link.subscriber_service_instance, si)

    def test_associate_onu(self):
        with patch.object(ServiceInstance.objects, "get") as get_si, \
            patch.object(ONUDevice.objects, "get") as get_onu:

            mock_si = Mock()
            mock_si.get_westbound_service_instance_properties.return_value = "BRCM1234"
            get_si.return_value = mock_si

            mock_onu = Mock()
            mock_onu.id = 12
            get_onu.return_value = mock_onu

            self.policy.associate_onu_device(self.si)

            self.assertEqual(self.si.onu_device_id, mock_onu.id)
            self.si.save.assert_called()

    def test_handle_delete(self):
        self.policy.handle_delete(self.si)
        # handle delete does nothing, and should trivially succeed

if __name__ == '__main__':
    unittest.main()

