/*
 * 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.VirtualPortEvent;
import org.onosproject.vtnrsc.virtualport.VirtualPortListener;
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 VirtualPortListener virtualPortListener = new InnerVirtualPortListener();

    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);
        virtualPortService.addListener(virtualPortListener);

        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);
        virtualPortService.removeListener(virtualPortListener);

        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)));
            }
        }
    }

    private class InnerVirtualPortListener implements VirtualPortListener {

        @Override
        public void event(VirtualPortEvent event) {
            checkNotNull(event, EVENT_NOT_NULL);
            VirtualPort virtualPort = event.subject();
            if (VirtualPortEvent.Type.VIRTUAL_PORT_PUT == event.type()) {
                notifyListeners(new VtnRscEvent(VtnRscEvent.Type.VIRTUAL_PORT_PUT,
                                                new VtnRscEventFeedback(virtualPort)));
            } else if (VirtualPortEvent.Type.VIRTUAL_PORT_DELETE == event.type()) {
                notifyListeners(new VtnRscEvent(VtnRscEvent.Type.VIRTUAL_PORT_DELETE,
                                                new VtnRscEventFeedback(virtualPort)));
            }
        }
    }

    @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);
    }
}
