# 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
import urllib
import functools
from mock import patch, call, Mock, PropertyMock
import requests_mock
import multistructlog
from multistructlog import create_logger

import os, sys

# Hack to load synchronizer framework
test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
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")
sys.path.append(xos_dir)
sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
# END Hack to load synchronizer framework

# generate model from xproto
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))
# END generate model from xproto

def match_json(desired, req):
    if desired!=req.json():
        raise Exception("Got request %s, but body is not matching" % req.url)
        return False
    return True

class TestSyncFabricPort(unittest.TestCase):

    def setUp(self):
        global DeferredException

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

        # Setting up the config module
        from xosconfig import Config
        config = os.path.join(test_path, "../test_config.yaml")
        Config.clear()
        Config.init(config, "synchronizer-config-schema.yaml")
        # END Setting up the config module

        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
        build_mock_modelaccessor(xos_dir, services_dir, [get_models_fn("fabric", "fabric.xproto")])
        import synchronizers.new_base.modelaccessor

        from sync_fabric_port import SyncFabricPort, model_accessor

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


        self.sync_step = SyncFabricPort
        self.sync_step.log = Mock()


        # mock onos-fabric
        onos_fabric = Mock()
        onos_fabric.name = "onos-fabric"
        onos_fabric.rest_hostname = "onos-fabric"
        onos_fabric.rest_port = "8181"
        onos_fabric.rest_username = "onos"
        onos_fabric.rest_password = "rocks"

        onos_fabric_base = Mock()
        onos_fabric_base.leaf_model = onos_fabric

        self.fabric = Mock()
        self.fabric.name = "fabric"
        self.fabric.provider_services = [onos_fabric_base]

        # create a mock SwitchPort instance
        self.o = Mock()
        self.o.id = 1
        self.o.tologdict.return_value = {}
        self.o.host_learning = True




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

    @requests_mock.Mocker()
    def test_sync_port(self, m):
        intf1 = Mock()
        intf1.name = "intf1"
        intf1.ips = "1.1.1.1/16"
        intf1.vlanUntagged = None

        self.o.interfaces.all.return_value = [intf1]
        self.o.switch.ofId = "of:1234"
        self.o.portId = "1"

        expected_conf = {
            "ports": {
                "%s/%s" % (self.o.switch.ofId, self.o.portId): {
                    "interfaces": [
                        {
                            "name": intf1.name,
                            "ips": [ intf1.ips ]
                        }
                    ],
                    "hostLearning": {
                        "enabled": self.o.host_learning
                    }
                }
            }
        }

        m.post("http://onos-fabric:8181/onos/v1/network/configuration/",
               status_code=200,
               additional_matcher=functools.partial(match_json, expected_conf))

        with patch.object(Service.objects, "get") as onos_fabric_get:
            onos_fabric_get.return_value = self.fabric

            self.sync_step().sync_record(self.o)

            self.assertTrue(m.called)

    @requests_mock.Mocker()
    def test_sync_port_with_vlan(self, m):
        intf1 = Mock()
        intf1.name = "intf1"
        intf1.ips = "1.1.1.1/16"
        intf1.vlanUntagged = 42

        self.o.interfaces.all.return_value = [intf1]
        self.o.switch.ofId = "of:1234"
        self.o.portId = "1"
        self.o.host_learning = False

        expected_conf = {
            "ports": {
                "%s/%s" % (self.o.switch.ofId, self.o.portId): {
                    "interfaces": [
                        {
                            "name": intf1.name,
                            "ips": [intf1.ips],
                            "vlan-untagged": intf1.vlanUntagged
                        }
                    ],
                    "hostLearning": {
                        "enabled": self.o.host_learning
                    }
                }
            }
        }

        m.post("http://onos-fabric:8181/onos/v1/network/configuration/",
               status_code=200,
               additional_matcher=functools.partial(match_json, expected_conf))

        with patch.object(Service.objects, "get") as onos_fabric_get:
            onos_fabric_get.return_value = self.fabric

            self.sync_step().sync_record(self.o)

            self.assertTrue(m.called)

    @requests_mock.Mocker()
    def test_delete_port(self, m):

        self.o.switch.ofId = "of:1234"
        self.o.portId = "1"

        key = urllib.quote("of:1234/1", safe='')

        m.delete("http://onos-fabric:8181/onos/v1/network/configuration/ports/%s" % key,
            status_code=204)

        with patch.object(Service.objects, "get") as onos_fabric_get:
            onos_fabric_get.return_value = self.fabric

            self.sync_step().delete_record(self.o)

            self.assertTrue(m.called)
