# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
#    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.
#

"""Test Library for OneConvergencePlugin."""

import contextlib
import uuid

import mock
from oslo_config import cfg

from neutron import context
from neutron.extensions import portbindings
from neutron import manager
from neutron.plugins.oneconvergence import plugin as nvsd_plugin
from neutron.tests.unit import _test_extension_portbindings as test_bindings
from neutron.tests.unit import test_db_plugin as test_plugin
from neutron.tests.unit import test_l3_plugin

PLUGIN_NAME = 'neutron.plugins.oneconvergence.plugin.OneConvergencePluginV2'


class OneConvergencePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase):
    _plugin_name = PLUGIN_NAME

    def setUp(self):
        if 'v6' in self._testMethodName:
            self.skipTest("NVSD Plugin does not support IPV6.")

        def mocked_oneconvergence_init(self):
            def side_effect(*args, **kwargs):
                return {'id': str(uuid.uuid4())}

            self.nvsdlib = mock.Mock()
            self.nvsdlib.create_network.side_effect = side_effect

        with mock.patch.object(nvsd_plugin.OneConvergencePluginV2,
                               'oneconvergence_init',
                               new=mocked_oneconvergence_init):
            super(OneConvergencePluginV2TestCase,
                  self).setUp(self._plugin_name)


class TestOneConvergencePluginNetworksV2(test_plugin.TestNetworksV2,
                                         OneConvergencePluginV2TestCase):
    pass


class TestOneConvergencePluginSubnetsV2(test_plugin.TestSubnetsV2,
                                        OneConvergencePluginV2TestCase):
    pass


class TestOneConvergencePluginPortsV2(test_plugin.TestPortsV2,
                                      test_bindings.PortBindingsTestCase,
                                      OneConvergencePluginV2TestCase):
    VIF_TYPE = portbindings.VIF_TYPE_OVS

    def test_port_vif_details(self):
        plugin = manager.NeutronManager.get_plugin()
        with self.port(name='name') as port1:
            ctx = context.get_admin_context()
            port = plugin.get_port(ctx, port1['port']['id'])
            self.assertEqual(port['binding:vif_type'],
                             portbindings.VIF_TYPE_OVS)

    def test_ports_vif_details(self):
        cfg.CONF.set_default('allow_overlapping_ips', True)
        plugin = manager.NeutronManager.get_plugin()
        with contextlib.nested(self.port(), self.port()) as (port1, port2):
            ctx = context.get_admin_context()
            ports = plugin.get_ports(ctx)
            self.assertEqual(len(ports), 2)
            for port in ports:
                self.assertEqual(port['binding:vif_type'],
                                 portbindings.VIF_TYPE_OVS)


class TestOneConvergenceBasicGet(test_plugin.TestBasicGet,
                                 OneConvergencePluginV2TestCase):
    pass


class TestOneConvergenceV2HTTPResponse(test_plugin.TestV2HTTPResponse,
                                       OneConvergencePluginV2TestCase):
    pass


class TestOneConvergenceL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase):
    _plugin_name = PLUGIN_NAME

    def setUp(self):
        if 'v6' in self._testMethodName:
            self.skipTest("NVSD Plugin does not support IPV6.")

        def mocked_oneconvergence_init(self):
            def side_effect(*args, **kwargs):
                return {'id': str(uuid.uuid4())}

            self.nvsdlib = mock.Mock()
            self.nvsdlib.create_network.side_effect = side_effect

        ext_mgr = test_l3_plugin.L3TestExtensionManager()

        with mock.patch.object(nvsd_plugin.OneConvergencePluginV2,
                               'oneconvergence_init',
                               new=mocked_oneconvergence_init):
            super(TestOneConvergenceL3NatTestCase,
                  self).setUp(plugin=self._plugin_name, ext_mgr=ext_mgr)

    def test_floatingip_with_invalid_create_port(self):
        self._test_floatingip_with_invalid_create_port(self._plugin_name)
