/*
 * Copyright 2015 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.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> l3vniMap;
    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 L3VNIMAP = "l3vniMap";
    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);
        l3vniMap = storageService
                .<TenantId, SegmentationId>eventuallyConsistentMapBuilder()
                .withName(L3VNIMAP).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);

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

    @Override
    public SegmentationId getL3vni(TenantId tenantId) {
        checkNotNull(tenantId, "tenantId cannot be null");
        SegmentationId l3vni = l3vniMap.get(tenantId);
        if (l3vni == null) {
            long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
                    .getNewId();
            l3vni = SegmentationId.segmentationId(String
                    .valueOf(segmentationId));
            l3vniMap.put(tenantId, 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);
    }
}
