/*
 * 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.
 */
package org.onosproject.openstacknode.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.GroupId;
import org.onosproject.net.Annotations;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.DefaultBridgeDescription;
import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.PatchDescription;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceAdminService;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceInterfaceDescription;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.flow.instructions.ExtensionPropertyException;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import org.onosproject.net.group.DefaultGroup;
import org.onosproject.net.group.Group;
import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupEvent;
import org.onosproject.net.group.GroupKey;
import org.onosproject.net.group.GroupListener;
import org.onosproject.net.group.GroupService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbController;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.MoreExecutors;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.net.Device.Type.CONTROLLER;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
import static org.onosproject.openstacknode.api.Constants.ROUTER_BRIDGE;
import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
import static org.onosproject.openstacknode.api.NodeState.INIT;
import static org.onosproject.openstacknode.api.NodeState.PORT_CREATED;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;

/**
 * Unit test for DefaultOpenstackNodeHandler.
 */
public class DefaultOpenstackNodeHandlerTest {

    private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
    private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
    private static final NodeId LOCAL_NODE_ID = new NodeId("local");
    private static final ControllerNode LOCAL_CTRL =
            new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));

    private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
            .name(ROUTER_BRIDGE)
            .failMode(BridgeDescription.FailMode.SECURE)
            .disableInBand()
            .build();

    private static final PortDescription PATCH_ROUT = new DefaultPortDescription(
            PortNumber.portNumber(1),
            true,
            DefaultAnnotations.builder()
                    .set(PORT_NAME, PATCH_ROUT_BRIDGE)
                    .build()
    );

    private static final String COMPUTE_1_HOSTNAME = "compute_1";
    private static final String COMPUTE_2_HOSTNAME = "compute_2";
    private static final String COMPUTE_3_HOSTNAME = "compute_3";
    private static final String COMPUTE_4_HOSTNAME = "compute_4";
    private static final String GATEWAY_1_HOSTNAME = "gateway_1";
    private static final String GATEWAY_2_HOSTNAME = "gateway_2";
    private static final String GATEWAY_3_HOSTNAME = "gateway_3";
    private static final String GATEWAY_4_HOSTNAME = "gateway_4";

    private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
    private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
    private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
    private static final IpAddress COMPUTE_4_IP = IpAddress.valueOf("10.100.0.4");
    private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
    private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
    private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
    private static final IpAddress GATEWAY_4_IP = IpAddress.valueOf("10.100.0.8");

    private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
    private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
    private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
    private static final Device COMPUTE_4_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
    private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
    private static final Device GATEWAY_1_ROUT_DEVICE = createOpenFlowDevice(6, ROUTER_BRIDGE);
    private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(7, INTEGRATION_BRIDGE);
    private static final Device GATEWAY_2_ROUT_DEVICE = createOpenFlowDevice(8, ROUTER_BRIDGE);
    private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(9, INTEGRATION_BRIDGE);
    private static final Device GATEWAY_3_ROUT_DEVICE = createOpenFlowDevice(10, ROUTER_BRIDGE);
    private static final Device GATEWAY_4_INTG_DEVICE = createOpenFlowDevice(11, INTEGRATION_BRIDGE);
    private static final Device GATEWAY_4_ROUT_DEVICE = createOpenFlowDevice(12, ROUTER_BRIDGE);

    private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
    private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
    private static final Device COMPUTE_3_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_3_IP);
    private static final Device COMPUTE_4_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_4_IP);
    private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
    private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);

    private static final OpenstackNode COMPUTE_1 = createNode(
            COMPUTE_1_HOSTNAME,
            COMPUTE,
            COMPUTE_1_INTG_DEVICE,
            COMPUTE_1_IP,
            INIT
    );

    private static final OpenstackNode COMPUTE_2 = createNode(
            COMPUTE_2_HOSTNAME,
            COMPUTE,
            COMPUTE_2_INTG_DEVICE,
            COMPUTE_2_IP,
            DEVICE_CREATED
    );

    private static final OpenstackNode COMPUTE_3 = createNode(
            COMPUTE_3_HOSTNAME,
            COMPUTE,
            COMPUTE_3_INTG_DEVICE,
            COMPUTE_3_IP,
            PORT_CREATED
    );

    private static final OpenstackNode COMPUTE_4 = createNode(
            COMPUTE_4_HOSTNAME,
            COMPUTE,
            COMPUTE_4_INTG_DEVICE,
            COMPUTE_4_IP,
            COMPLETE
    );

    private static final OpenstackNode GATEWAY_1 = createNode(
            GATEWAY_1_HOSTNAME,
            GATEWAY,
            GATEWAY_1_INTG_DEVICE,
            GATEWAY_1_ROUT_DEVICE,
            GATEWAY_1_IP,
            INIT
    );

    private static final OpenstackNode GATEWAY_2 = createNode(
            GATEWAY_2_HOSTNAME,
            GATEWAY,
            GATEWAY_2_INTG_DEVICE,
            GATEWAY_2_ROUT_DEVICE,
            GATEWAY_2_IP,
            DEVICE_CREATED
    );

    private static final OpenstackNode GATEWAY_3 = createNode(
            GATEWAY_3_HOSTNAME,
            GATEWAY,
            GATEWAY_3_INTG_DEVICE,
            GATEWAY_3_ROUT_DEVICE,
            GATEWAY_3_IP,
            PORT_CREATED
    );

    private static final OpenstackNode GATEWAY_4 = createNode(
            GATEWAY_4_HOSTNAME,
            GATEWAY,
            GATEWAY_4_INTG_DEVICE,
            GATEWAY_4_ROUT_DEVICE,
            GATEWAY_4_IP,
            COMPLETE
    );

    private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();

    private TestOpenstackNodeManager testNodeManager;
    private DefaultOpenstackNodeHandler target;

    @Before
    public void setUp() throws Exception {
        DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
        mockDeviceAdminService.removeDevice(anyObject());
        replay(mockDeviceAdminService);

        OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
        expect(mockOvsdbClient.isConnected())
                .andReturn(true)
                .anyTimes();
        replay(mockOvsdbClient);

        OvsdbController mockOvsdbController = createMock(OvsdbController.class);
        expect(mockOvsdbController.getOvsdbClient(anyObject()))
                .andReturn(mockOvsdbClient)
                .anyTimes();
        replay(mockOvsdbController);

        testNodeManager = new TestOpenstackNodeManager();
        target = new DefaultOpenstackNodeHandler();

        target.coreService = new TestCoreService();
        target.leadershipService = new TestLeadershipService();
        target.clusterService = new TestClusterService();
        target.deviceService = TEST_DEVICE_SERVICE;
        target.deviceAdminService = mockDeviceAdminService;
        target.ovsdbController = mockOvsdbController;
        target.groupService = new TestGroupService();
        target.osNodeService = testNodeManager;
        target.osNodeAdminService = testNodeManager;
        target.componentConfigService = new TestComponentConfigService();
        TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
        target.activate();
    }

    @After
    public void tearDown() {
        TEST_DEVICE_SERVICE.clear();
        target.deactivate();
        target = null;
        testNodeManager = null;
    }

    /**
     * Checks if the compute node state changes from INIT to DEVICE_CREATED
     * after processing INIT state.
     */
    @Test
    public void testComputeNodeProcessNodeInitState() {
        testNodeManager.createNode(COMPUTE_1);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, INIT,
                testNodeManager.node(COMPUTE_1_HOSTNAME).state());
        target.processInitState(COMPUTE_1);
        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
                testNodeManager.node(COMPUTE_1_HOSTNAME).state());
    }

    /**
     * Checks if the gateway node state changes from INIT to DEVICE_CREATED
     * after processing INIT state.
     */
    @Test
    public void testGatewayNodeProcessNodeInitState() {
        testNodeManager.createNode(GATEWAY_1);
        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, INIT,
                testNodeManager.node(GATEWAY_1_HOSTNAME).state());
        target.processInitState(GATEWAY_1);
        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
                testNodeManager.node(GATEWAY_1_HOSTNAME).state());
    }

    /**
     * Checks if the compute node state changes from DEVICE_CREATED to
     * PORT_CREATED after processing DEVICE_CREATED state.
     */
    @Test
    public void testComputeNodeProcessDeviceCreatedState() {
        testNodeManager.createNode(COMPUTE_2);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
                testNodeManager.node(COMPUTE_2_HOSTNAME).state());
        target.processDeviceCreatedState(COMPUTE_2);
        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
                testNodeManager.node(COMPUTE_2_HOSTNAME).state());
    }

    /**
     * Checks if the gateway node state changes from DEVICE_CREATED to
     * PORT_CREATED after processing DEVICE_CREATED state.
     */
    @Test
    public void testGatewayNodeProcessDeviceCreatedState() {
        testNodeManager.createNode(GATEWAY_2);
        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
                testNodeManager.node(GATEWAY_2_HOSTNAME).state());
        target.processDeviceCreatedState(GATEWAY_2);
        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
                testNodeManager.node(GATEWAY_2_HOSTNAME).state());
    }

    /**
     * Checks if the compute node state changes from PORT_CREATED to
     * COMPLETE after processing PORT_CREATED state.
     */
    @Test
    public void testComputeNodeProcessPortCreatedState() {
        testNodeManager.createNode(COMPUTE_3);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_OVSDB_DEVICE.id(), COMPUTE_3_OVSDB_DEVICE);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_INTG_DEVICE.id(), COMPUTE_3_INTG_DEVICE);
        TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));

        testNodeManager.createNode(GATEWAY_4);
        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_4_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
                testNodeManager.node(COMPUTE_3_HOSTNAME).state());
        target.processPortCreatedState(COMPUTE_3);
        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
                testNodeManager.node(COMPUTE_3_HOSTNAME).state());
    }

    /**
     * Checks if the gateway node state changes from PORT_CREATED to
     * COMPLETE after processing PORT_CREATED state.
     */
    @Test
    public void testGatewayNodeProcessPortCreatedState() {
        testNodeManager.createNode(COMPUTE_4);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_OVSDB_DEVICE.id(), COMPUTE_4_OVSDB_DEVICE);
        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_INTG_DEVICE.id(), COMPUTE_4_INTG_DEVICE);
        TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL));

        testNodeManager.createNode(GATEWAY_3);
        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_3_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE);

        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
                testNodeManager.node(GATEWAY_3_HOSTNAME).state());
        target.processPortCreatedState(GATEWAY_3);
        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
                testNodeManager.node(GATEWAY_3_HOSTNAME).state());
    }

    /**
     * Checks if the compute node state changes from COMPLETE to INCOMPLETE
     * when integration bridge is disconnected.
     */
    @Test
    public void testBackToIncompleteWhenBrIntDisconnected() {
        testNodeManager.createNode(COMPUTE_4);

        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
        TEST_DEVICE_SERVICE.removeDevice(COMPUTE_4_INTG_DEVICE);
        assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
    }

    /**
     * Checks if the compute node state changes from COMPLETE to INCOMPLETE
     * when vxlan port is removed from integration bridge.
     */
    @Test
    public void testBackToIncompleteWhenVxlanRemoved() {
        testNodeManager.createNode(COMPUTE_4);

        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
        TEST_DEVICE_SERVICE.removePort(COMPUTE_4_INTG_DEVICE, createPort(
                COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL));
        assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
                testNodeManager.node(COMPUTE_4_HOSTNAME).state());

    }

    private static Device createOvsdbDevice(IpAddress ovsdbIp) {
        return new TestDevice(new ProviderId("of", "foo"),
                DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
                CONTROLLER,
                "manufacturer",
                "hwVersion",
                "swVersion",
                "serialNumber",
                new ChassisId(1));
    }

    private static Device createOpenFlowDevice(long devIdNum, String type) {
        return new TestDevice(new ProviderId("of", "foo"),
                DeviceId.deviceId(String.format("of:%016d", devIdNum)),
                SWITCH,
                type,
                "hwVersion",
                "swVersion",
                "serialNumber",
                new ChassisId(1));
    }

    private static Port createPort(Device device, String portName) {
        return new DefaultPort(device,
                PortNumber.portNumber(1),
                true,
                DefaultAnnotations.builder().set(PORT_NAME, portName).build());
    }

    private static OpenstackNode createNode(String hostname,
                                            OpenstackNode.NodeType type,
                                            Device intgBridge,
                                            IpAddress ipAddr,
                                            NodeState state) {
        return new TestOpenstackNode(
                hostname,
                type,
                intgBridge.id(),
                null,
                ipAddr,
                ipAddr,
                null, state);
    }

    private static OpenstackNode createNode(String hostname,
                                            OpenstackNode.NodeType type,
                                            Device intgBridge,
                                            Device routerBridge,
                                            IpAddress ipAddr,
                                            NodeState state) {
        return new TestOpenstackNode(
                hostname,
                type,
                intgBridge.id(),
                routerBridge.id(),
                ipAddr,
                ipAddr,
                null, state);
    }

    private static final class TestDevice extends DefaultDevice {
        private TestDevice(ProviderId providerId,
                           DeviceId id,
                           Type type,
                           String manufacturer,
                           String hwVersion,
                           String swVersion,
                           String serialNumber,
                           ChassisId chassisId,
                           Annotations... annotations) {
            super(providerId,
                    id,
                    type,
                    manufacturer,
                    hwVersion,
                    swVersion,
                    serialNumber,
                    chassisId,
                    annotations);
        }

        @Override
        @SuppressWarnings("unchecked")
        public <B extends Behaviour> B as(Class<B> projectionClass) {
            if (projectionClass.equals(BridgeConfig.class)) {
                return (B) new TestBridgeConfig();
            } else if (projectionClass.equals(InterfaceConfig.class)) {
                return (B) new TestInterfaceConfig();
            } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
                ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
                expect(treatmentResolver.getExtensionInstruction(anyObject()))
                        .andReturn(new TestExtensionTreatment())
                        .anyTimes();
                replay(treatmentResolver);
                return (B) treatmentResolver;
            } else {
                return null;
            }
        }

        @Override
        public <B extends Behaviour> boolean is(Class<B> projectionClass) {
            return true;
        }
    }

    private static final class TestOpenstackNode extends DefaultOpenstackNode {
        private TestOpenstackNode(String hostname,
                                  NodeType type,
                                  DeviceId intgBridge,
                                  DeviceId routerBridge,
                                  IpAddress managementIp,
                                  IpAddress dataIp,
                                  String vlanIntf,
                                  NodeState state) {
            super(hostname,
                    type,
                    intgBridge,
                    routerBridge,
                    managementIp,
                    dataIp,
                    vlanIntf,
                    state);
        }

        @Override
        public PortNumber tunnelPortNum() {
            return PortNumber.portNumber(1);
        }

        @Override
        public PortNumber vlanPortNum() {
            return PortNumber.portNumber(1);
        }

        @Override
        public PortNumber patchPortNum() {
            return PortNumber.portNumber(1);
        }

        @Override
        public MacAddress vlanPortMac() {
            return MacAddress.NONE;
        }
    }

    private static class TestOpenstackNodeManager implements OpenstackNodeService, OpenstackNodeAdminService {
        Map<String, OpenstackNode> osNodeMap = Maps.newHashMap();
        List<OpenstackNodeListener> listeners = Lists.newArrayList();

        @Override
        public Set<OpenstackNode> nodes() {
            return ImmutableSet.copyOf(osNodeMap.values());
        }

        @Override
        public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.type() == type)
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<OpenstackNode> completeNodes() {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.state() == COMPLETE)
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.type() == type && osNode.state() == COMPLETE)
                    .collect(Collectors.toSet());
        }

        @Override
        public OpenstackNode node(String hostname) {
            return osNodeMap.get(hostname);
        }

        @Override
        public OpenstackNode node(DeviceId deviceId) {
            return osNodeMap.values().stream()
                    .filter(osNode -> Objects.equals(osNode.intgBridge(), deviceId) ||
                            Objects.equals(osNode.ovsdb(), deviceId) ||
                            Objects.equals(osNode.routerBridge(), deviceId))
                    .findFirst().orElse(null);
        }

        @Override
        public void addListener(OpenstackNodeListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeListener(OpenstackNodeListener listener) {
            listeners.remove(listener);
        }

        @Override
        public void createNode(OpenstackNode osNode) {
            osNodeMap.put(osNode.hostname(), osNode);
        }

        @Override
        public void updateNode(OpenstackNode osNode) {
            osNodeMap.put(osNode.hostname(), osNode);
        }

        @Override
        public OpenstackNode removeNode(String hostname) {
            return null;
        }
    }

    private static class TestDeviceService extends DeviceServiceAdapter {
        Map<DeviceId, Device> devMap = Maps.newHashMap();
        List<Port> portList = Lists.newArrayList();
        List<DeviceListener> listeners = Lists.newArrayList();

        @Override
        public void addListener(DeviceListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeListener(DeviceListener listener) {
            listeners.remove(listener);
        }

        @Override
        public Device getDevice(DeviceId deviceId) {
            return devMap.get(deviceId);
        }

        @Override
        public List<Port> getPorts(DeviceId deviceId) {
            return this.portList.stream()
                    .filter(p -> p.element().id().equals(deviceId))
                    .collect(Collectors.toList());
        }

        @Override
        public boolean isAvailable(DeviceId deviceId) {
            return devMap.containsKey(deviceId);
        }

        void addDevice(Device device) {
            devMap.put(device.id(), device);
            DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
        }

        void removeDevice(Device device) {
            devMap.remove(device.id());
            DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
        }

        void addPort(Device device, Port port) {
            portList.add(port);
            DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
        }

        void removePort(Device device, Port port) {
            portList.remove(port);
            DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
        }

        void clear() {
            this.listeners.clear();
            this.devMap.clear();
            this.portList.clear();
        }
    }

    private static class TestBridgeConfig implements BridgeConfig {

        @Override
        public DriverData data() {
            return null;
        }

        @Override
        public void setData(DriverData data) {

        }

        @Override
        public DriverHandler handler() {
            return null;
        }

        @Override
        public void setHandler(DriverHandler handler) {

        }

        @Override
        public boolean addBridge(BridgeDescription bridge) {
            TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
                    DeviceId.deviceId("of:" + bridge.datapathId().get()),
                    SWITCH,
                    bridge.name(),
                    "hwVersion",
                    "swVersion",
                    "serialNumber",
                    new ChassisId(1)));
            return true;
        }

        @Override
        public void deleteBridge(BridgeName bridgeName) {

        }

        @Override
        public Collection<BridgeDescription> getBridges() {
            return ImmutableSet.of(ROUT_BRIDGE);
        }

        @Override
        public void addPort(BridgeName bridgeName, String portName) {

        }

        @Override
        public void deletePort(BridgeName bridgeName, String portName) {

        }

        @Override
        public Collection<PortDescription> getPorts() {
            return ImmutableSet.of(PATCH_ROUT);
        }

        @Override
        public Set<PortNumber> getPortNumbers() {
            return null;
        }

        @Override
        public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
            return null;
        }
    }

    private static class TestInterfaceConfig implements InterfaceConfig {

        @Override
        public DriverData data() {
            return null;
        }

        @Override
        public void setData(DriverData data) {

        }

        @Override
        public DriverHandler handler() {
            return null;
        }

        @Override
        public void setHandler(DriverHandler handler) {

        }

        @Override
        public boolean addAccessMode(String intf, VlanId vlanId) {
            return false;
        }

        @Override
        public boolean removeAccessMode(String intf) {
            return false;
        }

        @Override
        public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
            return false;
        }

        @Override
        public boolean removeTrunkMode(String intf) {
            return false;
        }

        @Override
        public boolean addRateLimit(String intf, short limit) {
            return false;
        }

        @Override
        public boolean removeRateLimit(String intf) {
            return false;
        }

        @Override
        public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
            TEST_DEVICE_SERVICE.devMap.values().stream()
                    .filter(device -> device.type() == SWITCH &&
                            device.manufacturer().equals(INTEGRATION_BRIDGE))
                    .forEach(device -> {
                        TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
                    });
            return true;
        }

        @Override
        public boolean removeTunnelMode(String intf) {
            return false;
        }

        @Override
        public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
            if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
                TEST_DEVICE_SERVICE.devMap.values().stream()
                        .filter(device -> device.type() == SWITCH &&
                                device.manufacturer().equals(INTEGRATION_BRIDGE))
                        .forEach(device -> {
                            TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
                        });
            } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
                TEST_DEVICE_SERVICE.devMap.values().stream()
                        .filter(device -> device.type() == SWITCH &&
                                device.manufacturer().equals(ROUTER_BRIDGE))
                        .forEach(device -> {
                            TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
                        });
            }
            return true;
        }

        @Override
        public boolean removePatchMode(String ifaceName) {
            return false;
        }

        @Override
        public List<DeviceInterfaceDescription> getInterfaces() {
            return null;
        }
    }

    private static class TestGroupService implements GroupService {
        Map<GroupKey, Group> groupMap = Maps.newHashMap();
        Map<GroupKey, GroupBuckets> groupBucketsMap = Maps.newHashMap();
        List<GroupListener> listeners = Lists.newArrayList();

        @Override
        public void addListener(GroupListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeListener(GroupListener listener) {
            listeners.remove(listener);
        }

        @Override
        public void addGroup(GroupDescription groupDesc) {
            DefaultGroup group = new DefaultGroup(GroupId.valueOf(groupDesc.givenGroupId()), groupDesc);
            group.setState(Group.GroupState.ADDED);
            groupMap.put(groupDesc.appCookie(), group);
            groupBucketsMap.put(groupDesc.appCookie(), groupDesc.buckets());

            GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_ADDED, group);
            listeners.stream().filter(listener -> listener.isRelevant(event))
                    .forEach(listener -> listener.event(event));
        }

        @Override
        public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
            return groupMap.get(appCookie);
        }

        @Override
        public void addBucketsToGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
                                      GroupKey newCookie, ApplicationId appId) {

        }

        @Override
        public void removeBucketsFromGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
                                           GroupKey newCookie, ApplicationId appId) {

        }

        @Override
        public void purgeGroupEntries(DeviceId deviceId) {

        }

        @Override
        public void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId) {

        }

        @Override
        public Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId) {
            return null;
        }

        @Override
        public Iterable<Group> getGroups(DeviceId deviceId) {
            return null;
        }

        @Override
        public void setBucketsForGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
                                       GroupKey newCookie, ApplicationId appId) {
            groupBucketsMap.put(newCookie, buckets);
            GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_UPDATED, groupMap.get(newCookie));
            listeners.stream().filter(listener -> listener.isRelevant(event))
                    .forEach(listener -> listener.event(event));
        }

    }

    private static class TestExtensionTreatment implements ExtensionTreatment {
        Ip4Address tunnelDst;

        @Override
        public ExtensionTreatmentType type() {
            return null;
        }

        @Override
        public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
            tunnelDst = (Ip4Address) value;
        }

        @Override
        public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
            return null;
        }

        @Override
        public List<String> getProperties() {
            return null;
        }

        @Override
        public byte[] serialize() {
            return new byte[0];
        }

        @Override
        public void deserialize(byte[] data) {

        }

        @Override
        public boolean equals(Object obj) {
            TestExtensionTreatment that = (TestExtensionTreatment) obj;
            return Objects.equals(tunnelDst, that.tunnelDst);
        }

        @Override
        public int hashCode() {
            return Objects.hash(tunnelDst);
        }
    }

    private static class TestCoreService extends CoreServiceAdapter {

        @Override
        public ApplicationId getAppId(String name) {
            return TEST_APP_ID;
        }
    }

    private static class TestLeadershipService extends LeadershipServiceAdapter {

        @Override
        public NodeId getLeader(String path) {
            return LOCAL_NODE_ID;
        }
    }

    private static class TestClusterService extends ClusterServiceAdapter {

        @Override
        public ControllerNode getLocalNode() {
            return LOCAL_CTRL;
        }
    }

    private class TestComponentConfigService extends ComponentConfigAdapter {

    }
}
