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