/*
 * 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.unbindIdGenerator(idGenerator);
        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;
        }
    }
}
