/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.newoptical;

import org.apache.commons.lang3.tuple.Pair;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onlab.util.Bandwidth;
import org.onlab.util.Frequency;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.event.DefaultEventSinkRegistry;
import org.onosproject.event.Event;
import org.onosproject.event.EventDeliveryService;
import org.onosproject.event.EventSink;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Path;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.NetworkConfigServiceAdapter;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentServiceAdapter;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.optical.impl.DefaultOchPort;
import org.onosproject.net.optical.impl.DefaultOduCltPort;
import org.onosproject.net.optical.impl.DefaultOmsPort;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.resource.DiscreteResourceId;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.net.resource.ResourceId;
import org.onosproject.net.resource.ResourceListener;
import org.onosproject.net.resource.ResourceService;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.newoptical.api.OpticalConnectivityId;
import org.onosproject.newoptical.api.OpticalPathEvent;
import org.onosproject.newoptical.api.OpticalPathListener;
import org.onosproject.store.service.AsyncConsistentMap;
import org.onosproject.store.service.AsyncDistributedSet;
import org.onosproject.store.service.AtomicCounter;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.ConsistentMapAdapter;
import org.onosproject.store.service.ConsistentMapBuilder;
import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.DistributedSetAdapter;
import org.onosproject.store.service.DistributedSetBuilder;
import org.onosproject.store.service.MapEvent;
import org.onosproject.store.service.MapEventListener;
import org.onosproject.store.service.SetEventListener;
import org.onosproject.store.service.StorageServiceAdapter;
import org.onosproject.store.service.Versioned;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.google.common.base.Preconditions.checkState;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.NetTestTools.injectEventDispatcher;

/**
 * Tests for OpticalPathProvisioner class.
 */
public class OpticalPathProvisionerTest {

    private static final ProviderId PROVIDER_ID = new ProviderId("of", "foo");

    // 7-nodes linear topology containing packet/cross-connect/optical links
    private static final ConnectPoint CP11 = createConnectPoint(1, 1);
    private static final ConnectPoint CP12 = createConnectPoint(1, 2);
    private static final ConnectPoint CP21 = createConnectPoint(2, 1);
    private static final ConnectPoint CP22 = createConnectPoint(2, 2); // cross connect port (packet)
    private static final ConnectPoint CP31 = createConnectPoint(3, 1); // cross connect port (oductl)
    private static final ConnectPoint CP32 = createConnectPoint(3, 2);
    private static final ConnectPoint CP41 = createConnectPoint(4, 1);
    private static final ConnectPoint CP42 = createConnectPoint(4, 2);
    private static final ConnectPoint CP51 = createConnectPoint(5, 1);
    private static final ConnectPoint CP52 = createConnectPoint(5, 2); // cross connect port (oductl)
    private static final ConnectPoint CP61 = createConnectPoint(6, 1); // cross connect port (packet)
    private static final ConnectPoint CP62 = createConnectPoint(6, 2);
    private static final ConnectPoint CP71 = createConnectPoint(7, 1);
    private static final ConnectPoint CP72 = createConnectPoint(7, 2);

    private static final Link LINK1 = createLink(CP12, CP21, Link.Type.DIRECT);
    private static final Link LINK2 = createLink(CP22, CP31, Link.Type.OPTICAL); // cross connect link
    private static final Link LINK3 = createLink(CP32, CP41, Link.Type.OPTICAL);
    private static final Link LINK4 = createLink(CP42, CP51, Link.Type.OPTICAL);
    private static final Link LINK5 = createLink(CP52, CP61, Link.Type.OPTICAL); // cross connect link
    private static final Link LINK6 = createLink(CP62, CP71, Link.Type.DIRECT);

    private static final Device DEVICE1 = createDevice(1, Device.Type.SWITCH);
    private static final Device DEVICE2 = createDevice(2, Device.Type.SWITCH);
    private static final Device DEVICE3 = createDevice(3, Device.Type.ROADM);
    private static final Device DEVICE4 = createDevice(4, Device.Type.ROADM);
    private static final Device DEVICE5 = createDevice(5, Device.Type.ROADM);
    private static final Device DEVICE6 = createDevice(6, Device.Type.SWITCH);
    private static final Device DEVICE7 = createDevice(7, Device.Type.SWITCH);

    private static final Port PORT11 = createPacketPort(DEVICE1, CP11);
    private static final Port PORT12 = createPacketPort(DEVICE1, CP12);
    private static final Port PORT21 = createPacketPort(DEVICE2, CP21);
    private static final Port PORT22 = createOduCltPort(DEVICE2, CP22);
    private static final Port PORT31 = createOchPort(DEVICE3, CP31);
    private static final Port PORT32 = createOmsPort(DEVICE3, CP32);
    private static final Port PORT41 = createOmsPort(DEVICE4, CP41);
    private static final Port PORT42 = createOmsPort(DEVICE4, CP42);
    private static final Port PORT51 = createOmsPort(DEVICE5, CP51);
    private static final Port PORT52 = createOchPort(DEVICE5, CP52);
    private static final Port PORT61 = createOduCltPort(DEVICE6, CP61);
    private static final Port PORT62 = createPacketPort(DEVICE6, CP62);
    private static final Port PORT71 = createPacketPort(DEVICE7, CP71);
    private static final Port PORT72 = createPacketPort(DEVICE7, CP72);

    protected OpticalPathProvisioner target;
    protected TestListener listener = new TestListener();
    protected TestDeviceService deviceService;
    protected TestLinkService linkService;
    protected TestPathService pathService;
    protected TestIntentService intentService;
    protected TestMastershipService mastershipService;
    protected TestClusterService clusterService;
    protected IdGenerator idGenerator;

    @Before
    public void setUp() {
        this.deviceService = new TestDeviceService();
        deviceService.devMap.put(deviceIdOf(1), DEVICE1);
        deviceService.devMap.put(deviceIdOf(2), DEVICE2);
        deviceService.devMap.put(deviceIdOf(3), DEVICE3);
        deviceService.devMap.put(deviceIdOf(4), DEVICE4);
        deviceService.devMap.put(deviceIdOf(5), DEVICE5);
        deviceService.devMap.put(deviceIdOf(6), DEVICE6);
        deviceService.devMap.put(deviceIdOf(7), DEVICE7);
        deviceService.portMap.put(CP11, PORT11);
        deviceService.portMap.put(CP12, PORT12);
        deviceService.portMap.put(CP21, PORT21);
        deviceService.portMap.put(CP22, PORT22);
        deviceService.portMap.put(CP31, PORT31);
        deviceService.portMap.put(CP32, PORT32);
        deviceService.portMap.put(CP41, PORT41);
        deviceService.portMap.put(CP42, PORT42);
        deviceService.portMap.put(CP51, PORT51);
        deviceService.portMap.put(CP52, PORT52);
        deviceService.portMap.put(CP61, PORT61);
        deviceService.portMap.put(CP62, PORT62);
        deviceService.portMap.put(CP71, PORT71);
        deviceService.portMap.put(CP72, PORT72);

        this.linkService = new TestLinkService();
        linkService.links.addAll(Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
            .collect(Collectors.toList()));

        this.pathService = new TestPathService();
        this.intentService = new TestIntentService();
        this.mastershipService = new TestMastershipService();
        this.clusterService = new TestClusterService();

        mastershipService.setMastership(DEVICE1.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE2.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE3.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE4.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE5.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE6.id(), MastershipRole.MASTER);
        mastershipService.setMastership(DEVICE7.id(), MastershipRole.MASTER);

        this.target = new OpticalPathProvisioner();
        target.coreService = new TestCoreService();
        target.intentService = this.intentService;
        target.pathService = this.pathService;
        target.linkService = this.linkService;
        target.mastershipService = this.mastershipService;
        target.clusterService = this.clusterService;
        target.storageService = new TestStorageService();
        target.deviceService = this.deviceService;
        target.networkConfigService = new TestNetworkConfigService();
        target.resourceService = new TestResourceService();
        injectEventDispatcher(target, new TestEventDispatcher());
        target.addListener(listener);

        target.activate();

        // To overwrite opticalView-ed deviceService
        target.deviceService = this.deviceService;

        idGenerator = new IdGenerator() {
            int counter = 1;

            @Override
            public long getNewId() {
                return counter++;
            }
        };
        Intent.bindIdGenerator(idGenerator);
    }

    @After
    public void tearDown() {
        Intent.unbindIdGenerator(idGenerator);
        target.removeListener(listener);
        target = null;
    }

    /**
     * Checks setupConnectivity method works.
     */
    @Test
    public void testSetupConnectivity() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
        assertNotNull(cid);

        // Checks path computation is called as expected
        assertEquals(1, pathService.edges.size());
        assertEquals(CP12.deviceId(), pathService.edges.get(0).getKey());
        assertEquals(CP71.deviceId(), pathService.edges.get(0).getValue());

        // Checks intents are installed as expected
        assertEquals(1, intentService.submitted.size());
        assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
        assertEquals(CP31, connIntent.getSrc());
        assertEquals(CP52, connIntent.getDst());
    }

    /**
     * Checks setupPath method works.
     */
    @Test
    public void testSetupPath() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);
        List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
                .collect(Collectors.toList());
        Path path = new DefaultPath(PROVIDER_ID, links, 0);

        OpticalConnectivityId cid = target.setupPath(path, bandwidth, latency);
        assertNotNull(cid);

        // Checks intents are installed as expected
        assertEquals(1, intentService.submitted.size());
        assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
        assertEquals(CP31, connIntent.getSrc());
        assertEquals(CP52, connIntent.getDst());
    }

    /**
     * Checks removeConnectivity method works.
     */
    @Test
    public void testRemoveConnectivity() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);

        // Checks intents are withdrawn
        assertTrue(target.removeConnectivity(cid));
        assertEquals(1, intentService.withdrawn.size());
        assertEquals(OpticalConnectivityIntent.class, intentService.withdrawn.get(0).getClass());
        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.withdrawn.get(0);
        assertEquals(CP31, connIntent.getSrc());
        assertEquals(CP52, connIntent.getDst());
    }

    /**
     * Checks getPath method works.
     */
    @Test
    public void testGetPath() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);
        List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
                .collect(Collectors.toList());

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
        Optional<List<Link>> path = target.getPath(cid);

        // Checks returned path is as expected
        assertTrue(path.isPresent());
        assertEquals(links, path.get());
    }

    /**
     * Checks if PATH_INSTALLED event comes up after intent whose master is this node is installed.
     */
    @Test
    public void testInstalledEventLocal() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);

        // notify all intents are installed
        intentService.notifyInstalled();

        assertEquals(1, listener.events.size());
        assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type());
        assertEquals(cid, listener.events.get(0).subject());
    }

    /**
     * Checks if PATH_INSTALLED event comes up after intent whose master is remote node is installed.
     */
    @Test
    public void testInstalledEventRemote() {
        // set the master for ingress device of intent to remote node
        mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE);

        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);

        // notify all intents are installed
        intentService.notifyInstalled();

        // remote nodes must not receive event before distributed map is updated
        assertEquals(0, listener.events.size());
    }

    /**
     * Checks if PATH_REMOVED event comes up after packet link is removed.
     */
    @Test
    public void testRemovedEventLocal() {
        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);

        // notify all intents are installed
        intentService.notifyInstalled();

        target.removeConnectivity(cid);

        // notify all intents are withdrawn
        intentService.notifyWithdrawn();

        // must have received "INSTALLED" and "REMOVED" events
        assertEquals(2, listener.events.size());
        assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type());
        assertEquals(cid, listener.events.get(0).subject());
        assertEquals(OpticalPathEvent.Type.PATH_REMOVED, listener.events.get(1).type());
        assertEquals(cid, listener.events.get(1).subject());
    }


    /**
     * Checks if PATH_REMOVED event comes up after packet link is removed.
     */
    @Test
    public void testRemovedEventRemote() {
        // set the master for ingress device of intent to remote node
        mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE);

        Bandwidth bandwidth = Bandwidth.bps(100);
        Duration latency = Duration.ofMillis(10);

        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);

        // notify all intents are installed
        intentService.notifyInstalled();

        target.removeConnectivity(cid);

        // notify all intents are withdrawn
        intentService.notifyWithdrawn();

        // remote nodes must not receive event before distributed map is updated
        assertEquals(0, listener.events.size());
    }

    private static ConnectPoint createConnectPoint(long devIdNum, long portIdNum) {
        return new ConnectPoint(
                deviceIdOf(devIdNum),
                PortNumber.portNumber(portIdNum));
    }

    private static Link createLink(ConnectPoint src, ConnectPoint dst, Link.Type type) {
        return DefaultLink.builder()
                .providerId(PROVIDER_ID)
                .src(src)
                .dst(dst)
                .state(Link.State.ACTIVE)
                .type(type).build();
    }

    private static Device createDevice(long devIdNum, Device.Type type) {
        return new DefaultDevice(PROVIDER_ID,
                deviceIdOf(devIdNum),
                type,
                "manufacturer",
                "hwVersion",
                "swVersion",
                "serialNumber",
                new ChassisId(1));
    }

    private static Port createPacketPort(Device device, ConnectPoint cp) {
        return new DefaultPort(device, cp.port(), true);
    }

    private static Port createOchPort(Device device, ConnectPoint cp) {
        return new DefaultOchPort(new DefaultPort(device, cp.port(), true),
                OduSignalType.ODU4,
                true,
                OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1));
    }

    private static Port createOduCltPort(Device device, ConnectPoint cp) {
        return new DefaultOduCltPort(new DefaultPort(device, cp.port(), true),
                CltSignalType.CLT_100GBE);
    }

    private static Port createOmsPort(Device device, ConnectPoint cp) {
        return new DefaultOmsPort(new DefaultPort(device, cp.port(), true),
                Frequency.ofKHz(3),
                Frequency.ofKHz(33),
                Frequency.ofKHz(2));
    }

    private static DeviceId deviceIdOf(long devIdNum) {
        return DeviceId.deviceId(String.format("of:%016d", devIdNum));
    }

    private static class TestListener implements OpticalPathListener {
        final List<OpticalPathEvent> events = new ArrayList<>();

        @Override
        public void event(OpticalPathEvent event) {
            events.add(event);
        }
    }

    private static class TestPathService extends PathServiceAdapter {
        List<Pair<DeviceId, DeviceId>> edges = new ArrayList<>();

        @Override
        public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
            if (!(src instanceof DeviceId && dst instanceof DeviceId)) {
                return Collections.emptySet();
            }

            edges.add(Pair.of((DeviceId) src, (DeviceId) dst));

            Set<Path> paths = new HashSet<>();
            List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
                    .collect(Collectors.toList());
            paths.add(new DefaultPath(PROVIDER_ID, links, 0));

            // returns paths containing single path
            return paths;
        }

    }

    private static class TestIntentService extends IntentServiceAdapter {
        List<Intent> submitted = new ArrayList<>();
        List<Intent> withdrawn = new ArrayList<>();
        List<IntentListener> listeners = new ArrayList<>();

        @Override
        public void submit(Intent intent) {
            submitted.add(intent);
        }

        @Override
        public void withdraw(Intent intent) {
            withdrawn.add(intent);
        }

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

        @Override
        public Intent getIntent(Key intentKey) {
            Intent intent = submitted.stream().filter(i -> i.key().equals(intentKey))
                    .findAny()
                    .get();
            return intent;
        }

        void notifyInstalled() {
            submitted.forEach(i -> {
                IntentEvent event = new IntentEvent(IntentEvent.Type.INSTALLED, i);
                listeners.forEach(l -> l.event(event));
            });
        }

        void notifyWithdrawn() {
            withdrawn.forEach(i -> {
                IntentEvent event = new IntentEvent(IntentEvent.Type.WITHDRAWN, i);
                listeners.forEach(l -> l.event(event));
            });
        }

    }

    private static class TestLinkService extends LinkServiceAdapter {
        List<Link> links = new ArrayList<>();

        @Override
        public Set<Link> getLinks(ConnectPoint connectPoint) {
            return links.stream()
                    .filter(l -> l.src().equals(connectPoint) || l.dst().equals(connectPoint))
                    .collect(Collectors.toSet());
        }

    }

    private static class TestCoreService extends CoreServiceAdapter {
        @Override
        public ApplicationId registerApplication(String name) {
            return new DefaultApplicationId(0, name);
        }
    }

    private static class TestMastershipService extends MastershipServiceAdapter {
        private Map<DeviceId, MastershipRole> mastershipMap = new HashMap<>();

        public void setMastership(DeviceId deviceId, MastershipRole role) {
            mastershipMap.put(deviceId, role);
        }

        public void clear() {
            mastershipMap.clear();
        }

        @Override
        public MastershipRole getLocalRole(DeviceId deviceId) {
            return mastershipMap.get(deviceId);
        }

    }

    private static class TestClusterService extends ClusterServiceAdapter {
        private NodeId nodeId;

        public void setLocalNode(String nodeIdStr) {
            nodeId = NodeId.nodeId(nodeIdStr);
        }

        @Override
        public ControllerNode getLocalNode() {
            return new ControllerNode() {
                @Override
                public NodeId id() {
                    return nodeId;
                }

                @Override
                public IpAddress ip() {
                    return null;
                }

                @Override
                public int tcpPort() {
                    return 0;
                }
            };
        }
    }

    private static class TestStorageService extends StorageServiceAdapter {

        @Override
        public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
            ConsistentMapBuilder<K, V> builder = new ConsistentMapBuilder<K, V>() {
                @Override
                public AsyncConsistentMap<K, V> buildAsyncMap() {
                    return null;
                }

                @Override
                public ConsistentMap<K, V> build() {
                    return new TestConsistentMap<>();
                }
            };

            return builder;
        }

        @Override
        public <E> DistributedSetBuilder<E> setBuilder() {
            DistributedSetBuilder<E> builder = new DistributedSetBuilder<E>() {
                @Override
                public AsyncDistributedSet<E> build() {
                    return new DistributedSetAdapter<E>() {
                        @Override
                        public DistributedSet<E> asDistributedSet() {
                            return new TestDistributedSet<>();
                        }
                    };
                }
            };

            return builder;
        }

        @Override
        public AtomicCounter getAtomicCounter(String name) {
            return new MockAtomicCounter();
        }

        // Mock ConsistentMap that behaves as a HashMap
        class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
            private Map<K, Versioned<V>> map = new HashMap<>();
            private Map<MapEventListener<K, V>, Executor> listeners = new HashMap<>();

            public void notifyListeners(MapEvent<K, V> event) {
                listeners.forEach((c, e) -> e.execute(() -> c.event(event)));
            }

            @Override
            public int size() {
                return map.size();
            }

            @Override
            public Versioned<V> put(K key, V value) {
                Versioned<V> oldValue = map.get(key);
                Versioned<V> newValue = new Versioned<>(value, oldValue == null ? 0 : oldValue.version() + 1);
                map.put(key, newValue);
                notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
                return newValue;
            }

            @Override
            public Versioned<V> get(K key) {
                return map.get(key);
            }

            @Override
            public Versioned<V> remove(K key) {
                Versioned<V> oldValue = map.remove(key);
                notifyListeners(new MapEvent<>(name(), key, oldValue, null));
                return oldValue;
            }

            @Override
            public Versioned<V> computeIfPresent(K key,
                                                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
                Versioned<V> oldValue = map.get(key);
                Versioned<V> newValue = new Versioned<>(remappingFunction.apply(key, oldValue.value()),
                        oldValue == null ? 0 : oldValue.version() + 1);
                map.put(key, newValue);
                notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
                return newValue;
            }


            @Override
            public Set<Map.Entry<K, Versioned<V>>> entrySet() {
                return map.entrySet();
            }

            @Override
            public Set<K> keySet() {
                return map.keySet();
            }

            @Override
            public Collection<Versioned<V>> values() {
                return map.values();
            }

            @Override
            public void clear() {
                map.clear();
            }

            @Override
            public void addListener(MapEventListener<K, V> listener, Executor executor) {
                listeners.put(listener, executor);
            }

            @Override
            public void removeListener(MapEventListener<K, V> listener) {
                listeners.remove(listener);
            }
        }

        // Mock DistributedSet that behaves as a HashSet
        class TestDistributedSet<E> extends HashSet<E> implements DistributedSet<E> {

            @Override
            public void addListener(SetEventListener<E> listener) {
            }

            @Override
            public void removeListener(SetEventListener<E> listener) {
            }

            @Override
            public String name() {
                return null;
            }

            @Override
            public Type primitiveType() {
                return null;
            }
        }

    }

    private static class TestDeviceService extends DeviceServiceAdapter {
        Map<DeviceId, Device> devMap = new HashMap<>();
        Map<ConnectPoint, Port> portMap = new HashMap<>();

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

        @Override
        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
            return portMap.get(new ConnectPoint(deviceId, portNumber));
        }
    }

    private static class TestNetworkConfigService extends NetworkConfigServiceAdapter {
        @Override
        @SuppressWarnings("unchecked")
        public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
            if (BandwidthCapacity.class.equals(configClass)) {
                return (C) new BandwidthCapacity() {
                    @Override
                    public void apply() {
                        // do nothing
                    }

                    @Override
                    public BandwidthCapacity capacity(Bandwidth bandwidth) {
                        // do nothing
                        return this;
                    }
                };
            }
            return null;
        }

    }

    private static class TestResourceService implements ResourceService {

        @Override
        public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<? extends Resource> resources) {
            List<ResourceAllocation> allocations = new ArrayList<>();

            resources.forEach(r -> allocations.add(new ResourceAllocation(r, consumer.consumerId())));

            return allocations;
        }

        @Override
        public boolean release(List<ResourceAllocation> allocations) {
            return false;
        }

        @Override
        public boolean release(ResourceConsumer consumer) {

            return true;
        }

        @Override
        public void addListener(ResourceListener listener) {

        }

        @Override
        public void removeListener(ResourceListener listener) {

        }

        @Override
        public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
            return null;
        }

        @Override
        public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
            return null;
        }

        @Override
        public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
            return null;
        }

        @Override
        public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
            return null;
        }

        @Override
        public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
            return null;
        }

        @Override
        public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
            return null;
        }

        @Override
        public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
            return null;
        }

        @Override
        public boolean isAvailable(Resource resource) {
            return true;
        }
    }

    private static class MockAtomicCounter implements AtomicCounter {
        long id = 0;

        @Override
        public long incrementAndGet() {
            return ++id;
        }

        @Override
        public long getAndIncrement() {
            return id++;
        }

        @Override
        public long getAndAdd(long delta) {
            long oldId = id;
            id += delta;
            return oldId;
        }

        @Override
        public long addAndGet(long delta) {
            id += delta;
            return id;
        }

        @Override
        public void set(long value) {
            id = value;
        }

        @Override
        public boolean compareAndSet(long expectedValue, long updateValue) {
            if (id == expectedValue) {
                id = updateValue;
                return true;
            } else {
                return false;
            }
        }

        @Override
        public long get() {
            return id;
        }

        @Override
        public String name() {
            return "MockAtomicCounter";
        }
    }

    // copied from org.onosproject.common.event.impl.TestEventDispatcher
    /**
     * Implements event delivery system that delivers events synchronously, or
     * in-line with the post method invocation.
     */
    public class TestEventDispatcher extends DefaultEventSinkRegistry
            implements EventDeliveryService {

        @Override
        @SuppressWarnings("unchecked")
        public synchronized void post(Event event) {
            EventSink sink = getSink(event.getClass());
            checkState(sink != null, "No sink for event %s", event);
            sink.process(event);
        }

        @Override
        public void setDispatchTimeLimit(long millis) {
        }

        @Override
        public long getDispatchTimeLimit() {
            return 0;
        }
    }
}
