/*
 * Copyright 2015-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.vtnrsc.service.impl;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.CoreService;
import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.HostService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.FloatingIp;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.Router;
import org.onosproject.vtnrsc.RouterId;
import org.onosproject.vtnrsc.RouterInterface;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.Subnet;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantRouter;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.event.VtnRscEvent;
import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
import org.onosproject.vtnrsc.event.VtnRscListener;
import org.onosproject.vtnrsc.floatingip.FloatingIpEvent;
import org.onosproject.vtnrsc.floatingip.FloatingIpListener;
import org.onosproject.vtnrsc.floatingip.FloatingIpService;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
import org.onosproject.vtnrsc.portchain.PortChainEvent;
import org.onosproject.vtnrsc.portchain.PortChainListener;
import org.onosproject.vtnrsc.portchain.PortChainService;
import org.onosproject.vtnrsc.portpair.PortPairEvent;
import org.onosproject.vtnrsc.portpair.PortPairListener;
import org.onosproject.vtnrsc.portpair.PortPairService;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.onosproject.vtnrsc.router.RouterEvent;
import org.onosproject.vtnrsc.router.RouterListener;
import org.onosproject.vtnrsc.router.RouterService;
import org.onosproject.vtnrsc.routerinterface.RouterInterfaceEvent;
import org.onosproject.vtnrsc.routerinterface.RouterInterfaceListener;
import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;

/**
 * Provides implementation of the VtnRsc service.
 */
@Component(immediate = true)
@Service
public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener>
                           implements VtnRscService {
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService storageService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LogicalClockService clockService;

    private final Logger log = getLogger(getClass());
    private FloatingIpListener floatingIpListener = new InnerFloatingIpListener();
    private RouterListener routerListener = new InnerRouterListener();
    private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener();
    private PortPairListener portPairListener = new InnerPortPairListener();
    private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
    private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
    private PortChainListener portChainListener = new InnerPortChainListener();

    private EventuallyConsistentMap<TenantId, SegmentationId> l3vniTenantMap;
    private EventuallyConsistentMap<TenantRouter, SegmentationId> l3vniTenantRouterMap;
    private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap;
    private EventuallyConsistentMap<TenantId, Set<DeviceId>> sffOvsMap;

    private static final String IFACEID = "ifaceid";
    private static final String RUNNELOPTOPOIC = "tunnel-ops-ids";
    private static final String EVENT_NOT_NULL = "event cannot be null";
    private static final String TENANTID_NOT_NULL = "tenantId cannot be null";
    private static final String DEVICEID_NOT_NULL = "deviceId cannot be null";
    private static final String VIRTUALPORTID_NOT_NULL = "virtualPortId cannot be null";
    private static final String HOST_NOT_NULL = "host cannot be null";
    private static final String L3VNITENANTMAP = "l3vniTenantMap";
    private static final String L3VNITENANTROUTERMAP = "l3vniTenantRouterMap";
    private static final String CLASSIFIEROVSMAP = "classifierOvsMap";
    private static final String SFFOVSMAP = "sffOvsMap";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected RouterService routerService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FloatingIpService floatingIpService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected RouterInterfaceService routerInterfaceService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualPortService virtualPortService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected SubnetService subnetService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TenantNetworkService tenantNetworkService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortPairService portPairService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortPairGroupService portPairGroupService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowClassifierService flowClassifierService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PortChainService portChainService;

    @Activate
    public void activate() {
        eventDispatcher.addSink(VtnRscEvent.class, listenerRegistry);
        floatingIpService.addListener(floatingIpListener);
        routerService.addListener(routerListener);
        routerInterfaceService.addListener(routerInterfaceListener);
        portPairService.addListener(portPairListener);
        portPairGroupService.addListener(portPairGroupListener);
        flowClassifierService.addListener(flowClassifierListener);
        portChainService.addListener(portChainListener);

        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                .register(KryoNamespaces.API)
                .register(TenantId.class, DeviceId.class, SegmentationId.class,
                          TenantRouter.class, RouterId.class);
        l3vniTenantMap = storageService
                .<TenantId, SegmentationId>eventuallyConsistentMapBuilder()
                .withName(L3VNITENANTMAP).withSerializer(serializer)
                .withTimestampProvider((k, v) -> clockService.getTimestamp())
                .build();

        l3vniTenantRouterMap = storageService
                .<TenantRouter, SegmentationId>eventuallyConsistentMapBuilder()
                .withName(L3VNITENANTROUTERMAP).withSerializer(serializer)
                .withTimestampProvider((k, v) -> clockService.getTimestamp())
                .build();

        classifierOvsMap = storageService
                .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
                .withName(CLASSIFIEROVSMAP).withSerializer(serializer)
                .withTimestampProvider((k, v) -> clockService.getTimestamp())
                .build();

        sffOvsMap = storageService
                .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
                .withName(SFFOVSMAP).withSerializer(serializer)
                .withTimestampProvider((k, v) -> clockService.getTimestamp())
                .build();
    }

    @Deactivate
    public void deactivate() {
        eventDispatcher.removeSink(VtnRscEvent.class);
        floatingIpService.removeListener(floatingIpListener);
        routerService.removeListener(routerListener);
        routerInterfaceService.removeListener(routerInterfaceListener);
        portPairService.removeListener(portPairListener);
        portPairGroupService.removeListener(portPairGroupListener);
        flowClassifierService.removeListener(flowClassifierListener);
        portChainService.removeListener(portChainListener);

        l3vniTenantMap.destroy();
        l3vniTenantRouterMap.destroy();
        classifierOvsMap.destroy();
        sffOvsMap.destroy();
        log.info("Stopped");
    }

    @Override
    public SegmentationId getL3vni(TenantId tenantId) {
        checkNotNull(tenantId, "tenantId cannot be null");
        SegmentationId l3vni = l3vniTenantMap.get(tenantId);
        if (l3vni == null) {
            long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
                    .getNewId();
            l3vni = SegmentationId.segmentationId(String
                    .valueOf(segmentationId));
            l3vniTenantMap.put(tenantId, l3vni);
        }
        return l3vni;
    }

    @Override
    public SegmentationId getL3vni(TenantRouter tenantRouter) {
        checkNotNull(tenantRouter, "tenantRouter cannot be null");
        SegmentationId l3vni = l3vniTenantRouterMap.get(tenantRouter);
        if (l3vni == null) {
            long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
                    .getNewId();
            l3vni = SegmentationId.segmentationId(String
                    .valueOf(segmentationId));
            l3vniTenantRouterMap.put(tenantRouter, l3vni);
        }
        return l3vni;
    }

    private class InnerFloatingIpListener implements FloatingIpListener {

        @Override
        public void event(FloatingIpEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            FloatingIp floatingIp = event.subject();
            if (FloatingIpEvent.Type.FLOATINGIP_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.FLOATINGIP_PUT,
                                                new VtnRscEventFeedback(
                                                                        floatingIp)));
            }
            if (FloatingIpEvent.Type.FLOATINGIP_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.FLOATINGIP_DELETE,
                                                new VtnRscEventFeedback(
                                                                        floatingIp)));
            }
            if (FloatingIpEvent.Type.FLOATINGIP_BIND == event.type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.FLOATINGIP_BIND,
                                                new VtnRscEventFeedback(
                                                                        floatingIp)));
            }
            if (FloatingIpEvent.Type.FLOATINGIP_UNBIND == event.type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.FLOATINGIP_UNBIND,
                                                new VtnRscEventFeedback(
                                                                        floatingIp)));
            }
        }
    }

    private class InnerRouterListener implements RouterListener {

        @Override
        public void event(RouterEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            Router router = event.subject();
            if (RouterEvent.Type.ROUTER_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_PUT,
                                                new VtnRscEventFeedback(router)));
            }
            if (RouterEvent.Type.ROUTER_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_DELETE,
                                                new VtnRscEventFeedback(router)));
            }
        }
    }

    private class InnerRouterInterfaceListener
            implements RouterInterfaceListener {

        @Override
        public void event(RouterInterfaceEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            RouterInterface routerInterface = event.subject();
            if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.ROUTER_INTERFACE_PUT,
                                                new VtnRscEventFeedback(
                                                                        routerInterface)));
            }
            if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_DELETE == event
                    .type()) {
                notifyListeners(new VtnRscEvent(
                                                VtnRscEvent.Type.ROUTER_INTERFACE_DELETE,
                                                new VtnRscEventFeedback(
                                                                        routerInterface)));
            }
        }
    }

    private class InnerPortPairListener implements PortPairListener {

        @Override
        public void event(PortPairEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            PortPair portPair = event.subject();
            if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT,
                        new VtnRscEventFeedback(portPair)));
            } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_PAIR_DELETE,
                        new VtnRscEventFeedback(portPair)));
            } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_PAIR_UPDATE,
                        new VtnRscEventFeedback(portPair)));
            }
        }
    }

    private class InnerPortPairGroupListener implements PortPairGroupListener {

        @Override
        public void event(PortPairGroupEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            PortPairGroup portPairGroup = event.subject();
            if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_PAIR_GROUP_PUT,
                        new VtnRscEventFeedback(portPairGroup)));
            } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE,
                        new VtnRscEventFeedback(portPairGroup)));
            } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE,
                        new VtnRscEventFeedback(portPairGroup)));
            }
        }
    }

    private class InnerFlowClassifierListener implements FlowClassifierListener {

        @Override
        public void event(FlowClassifierEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            FlowClassifier flowClassifier = event.subject();
            if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.FLOW_CLASSIFIER_PUT,
                        new VtnRscEventFeedback(flowClassifier)));
            } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE,
                        new VtnRscEventFeedback(flowClassifier)));
            } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE,
                        new VtnRscEventFeedback(flowClassifier)));
            }
        }
    }

    private class InnerPortChainListener implements PortChainListener {

        @Override
        public void event(PortChainEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            PortChain portChain = event.subject();
            if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_CHAIN_PUT,
                        new VtnRscEventFeedback(portChain)));
            } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_CHAIN_DELETE,
                        new VtnRscEventFeedback(portChain)));
            } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
                notifyListeners(new VtnRscEvent(
                        VtnRscEvent.Type.PORT_CHAIN_UPDATE,
                        new VtnRscEventFeedback(portChain)));
            }
        }
    }

    @Override
    public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
        checkNotNull(tenantId, TENANTID_NOT_NULL);
        Set<DeviceId> deviceIdSet = classifierOvsMap.get(tenantId);
        Set<Device> deviceSet = new HashSet<>();
        if (deviceIdSet != null) {
            for (DeviceId deviceId : deviceIdSet) {
                deviceSet.add(deviceService.getDevice(deviceId));
            }
        }
        return deviceSet.iterator();
    }

    @Override
    public Iterator<Device> getSffOfTenant(TenantId tenantId) {
        checkNotNull(tenantId, TENANTID_NOT_NULL);
        Set<DeviceId> deviceIdSet = sffOvsMap.get(tenantId);
        Set<Device> deviceSet = new HashSet<>();
        if (deviceIdSet != null) {
            for (DeviceId deviceId : deviceIdSet) {
                deviceSet.add(deviceService.getDevice(deviceId));
            }
        }
        return deviceSet.iterator();
    }

    @Override
    public MacAddress getGatewayMac(HostId hostId) {
        checkNotNull(hostId, "hostId cannot be null");
        Host host = hostService.getHost(hostId);
        String ifaceId = host.annotations().value(IFACEID);
        VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
        VirtualPort hPort = virtualPortService.getPort(hPortId);
        SubnetId subnetId = hPort.fixedIps().iterator().next().subnetId();
        Subnet subnet = subnetService.getSubnet(subnetId);
        IpAddress gatewayIp = subnet.gatewayIp();
        Iterable<VirtualPort> virtualPorts = virtualPortService.getPorts();
        MacAddress macAddress = null;
        for (VirtualPort port : virtualPorts) {
            Set<FixedIp> fixedIpSet = port.fixedIps();
            for (FixedIp fixedIp : fixedIpSet) {
                if (fixedIp.ip().equals(gatewayIp)) {
                    macAddress = port.macAddress();
                }
            }
        }
        return macAddress;
    }

    @Override
    public boolean isServiceFunction(VirtualPortId portId) {
        return portPairService.exists(PortPairId.of(portId.portId()));
    }

    @Override
    public DeviceId getSfToSffMaping(VirtualPortId portId) {
        checkNotNull(portId, "portId cannot be null");
        VirtualPort vmPort = virtualPortService.getPort(portId);
        Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
        for (Host host : hostSet) {
            if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) {
                return host.location().deviceId();
            }
        }
        return null;
    }

    @Override
    public void addDeviceIdOfOvsMap(VirtualPortId virtualPortId,
                                    TenantId tenantId, DeviceId deviceId) {
        checkNotNull(virtualPortId, VIRTUALPORTID_NOT_NULL);
        checkNotNull(tenantId, TENANTID_NOT_NULL);
        checkNotNull(deviceId, DEVICEID_NOT_NULL);
        if (isServiceFunction(virtualPortId)) {
            addDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
        } else {
            addDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
        }
    }

    @Override
    public void removeDeviceIdOfOvsMap(Host host, TenantId tenantId, DeviceId deviceId) {
        checkNotNull(host, HOST_NOT_NULL);
        checkNotNull(tenantId, TENANTID_NOT_NULL);
        checkNotNull(deviceId, DEVICEID_NOT_NULL);
        if (isLastSFHostOfTenant(host, deviceId, tenantId)) {
            removeDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
        }
        if (isLastClassifierHostOfTenant(host, deviceId, tenantId)) {
            removeDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
        }
    }

    /**
     * Checks whether the last Service Function host of a specific tenant in
     * this device.
     *
     * @param host the host on device
     * @param deviceId the device identifier
     * @param tenantId the tenant identifier
     * @return true or false
     */
    private boolean isLastSFHostOfTenant(Host host, DeviceId deviceId,
                                         TenantId tenantId) {
        Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
        if (hostSet != null) {
            for (Host h : hostSet) {
                String ifaceId = h.annotations().value(IFACEID);
                if (ifaceId != null) {
                    VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
                    if (virtualPortService.getPort(hPortId).tenantId().tenantId()
                            .equals(tenantId.tenantId())
                            && isServiceFunction(hPortId)) {
                        if (!h.equals(host)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    /**
     * Checks whether the last Classifier host of a specific tenant in this
     * device.
     *
     * @param host the host on device
     * @param deviceId the device identifier
     * @param tenantId the tenant identifier
     * @return true or false
     */
    private boolean isLastClassifierHostOfTenant(Host host, DeviceId deviceId,
                                                 TenantId tenantId) {
        Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
        if (hostSet != null) {
            for (Host h : hostSet) {
                String ifaceId = h.annotations().value(IFACEID);
                if (ifaceId != null) {
                    VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
                    if (virtualPortService.getPort(hPortId).tenantId().tenantId()
                            .equals(tenantId.tenantId())
                            && !isServiceFunction(hPortId)) {
                        if (!h.equals(host)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    /**
     * Adds specify Device identifier to OvsMap.
     *
     * @param tenantId the tenant identifier
     * @param deviceId the device identifier
     * @param ovsMap the instance of map to store device identifier
     */
    private void addDeviceIdToSpecificMap(TenantId tenantId,
                                     DeviceId deviceId,
                                     EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
        if (ovsMap.containsKey(tenantId)) {
            Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
            deviceIdSet.add(deviceId);
            ovsMap.put(tenantId, deviceIdSet);
        } else {
            Set<DeviceId> deviceIdSet = new HashSet<>();
            deviceIdSet.add(deviceId);
            ovsMap.put(tenantId, deviceIdSet);
        }
    }

    /**
     * Removes specify Device identifier from OvsMap.
     *
     * @param tenantId the tenant identifier
     * @param deviceId the device identifier
     * @param ovsMap the instance of map to store device identifier
     */
    private void removeDeviceIdToSpecificMap(TenantId tenantId,
                                        DeviceId deviceId,
                                        EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
        Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
        if (deviceIdSet != null && deviceIdSet.size() > 1) {
            deviceIdSet.remove(deviceId);
            ovsMap.put(tenantId, deviceIdSet);
        } else {
            ovsMap.remove(tenantId);
        }
    }

    /**
     * Notifies specify event to all listeners.
     *
     * @param event VtnRsc event
     */
    private void notifyListeners(VtnRscEvent event) {
        checkNotNull(event, EVENT_NOT_NULL);
        post(event);
    }
}
