/*
 * Copyright 2014-present Open Networking Foundation
 *
 * 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.net.host.impl;

import com.google.common.collect.Sets;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicHostConfig;
import org.onosproject.net.config.basics.HostAnnotationConfig;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.host.HostAdminService;
import org.onosproject.net.host.HostDescription;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostProvider;
import org.onosproject.net.host.HostProviderRegistry;
import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.host.HostStore;
import org.onosproject.net.host.HostStoreDelegate;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;

import java.util.Dictionary;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.packet.IPv6.getLinkLocalAddress;
import static org.onlab.util.Tools.get;
import static org.onosproject.net.OsgiPropertyConstants.HM_ALLOW_DUPLICATE_IPS;
import static org.onosproject.net.OsgiPropertyConstants.HM_ALLOW_DUPLICATE_IPS_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_GREEDY_LEARNING_IPV6;
import static org.onosproject.net.OsgiPropertyConstants.HM_GREEDY_LEARNING_IPV6_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_MONITOR_HOSTS;
import static org.onosproject.net.OsgiPropertyConstants.HM_MONITOR_HOSTS_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_PROBE_RATE;
import static org.onosproject.net.OsgiPropertyConstants.HM_PROBE_RATE_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVED_THRESHOLD_IN_MILLIS;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVED_THRESHOLD_IN_MILLIS_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVE_COUNTER;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVE_COUNTER_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVE_TRACKER_ENABLE;
import static org.onosproject.net.OsgiPropertyConstants.HM_HOST_MOVE_TRACKER_ENABLE_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_OFFENDING_HOST_EXPIRY_IN_MINS;
import static org.onosproject.net.OsgiPropertyConstants.HM_OFFENDING_HOST_EXPIRY_IN_MINS_DEFAULT;
import static org.onosproject.net.OsgiPropertyConstants.HM_OFFENDING_HOST_THREADS_POOL_SIZE;
import static org.onosproject.net.OsgiPropertyConstants.HM_OFFENDING_HOST_THREADS_POOL_SIZE_DEFAULT;

import static org.onosproject.security.AppGuard.checkPermission;
import static org.onosproject.security.AppPermission.Type.HOST_EVENT;
import static org.onosproject.security.AppPermission.Type.HOST_READ;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provides basic implementation of the host SB &amp; NB APIs.
 */
@Component(
        immediate = true,
        service = {
            HostService.class,
            HostAdminService.class,
            HostProviderRegistry.class
        },
        property = {
                HM_ALLOW_DUPLICATE_IPS + ":Boolean=" + HM_ALLOW_DUPLICATE_IPS_DEFAULT,
                HM_MONITOR_HOSTS + ":Boolean=" + HM_MONITOR_HOSTS_DEFAULT,
                HM_PROBE_RATE + ":Integer=" + HM_PROBE_RATE_DEFAULT,
                HM_GREEDY_LEARNING_IPV6 + ":Boolean=" + HM_GREEDY_LEARNING_IPV6_DEFAULT,
                HM_HOST_MOVE_TRACKER_ENABLE + ":Boolean=" + HM_HOST_MOVE_TRACKER_ENABLE_DEFAULT,
                HM_HOST_MOVED_THRESHOLD_IN_MILLIS + ":Integer=" + HM_HOST_MOVED_THRESHOLD_IN_MILLIS_DEFAULT,
                HM_HOST_MOVE_COUNTER + ":Integer=" + HM_HOST_MOVE_COUNTER_DEFAULT,
                HM_OFFENDING_HOST_EXPIRY_IN_MINS + ":Long=" + HM_OFFENDING_HOST_EXPIRY_IN_MINS_DEFAULT,
                HM_OFFENDING_HOST_THREADS_POOL_SIZE + ":Integer=" + HM_OFFENDING_HOST_THREADS_POOL_SIZE_DEFAULT


        }
)
public class HostManager
        extends AbstractListenerProviderRegistry<HostEvent, HostListener, HostProvider, HostProviderService>
        implements HostService, HostAdminService, HostProviderRegistry {

    private final Logger log = getLogger(getClass());

    public static final String HOST_ID_NULL = "Host ID cannot be null";

    private final NetworkConfigListener networkConfigListener = new InternalNetworkConfigListener();

    private HostStoreDelegate delegate = new InternalStoreDelegate();

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected HostStore store;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected NetworkConfigService networkConfigService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected InterfaceService interfaceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected EdgePortService edgePortService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ComponentConfigService cfgService;

    /** Enable removal of duplicate ip address. */
    private boolean allowDuplicateIps = HM_ALLOW_DUPLICATE_IPS_DEFAULT;

    /** Enable/Disable monitoring of hosts. */
    private boolean monitorHosts = HM_MONITOR_HOSTS_DEFAULT;

    /** Set the probe Rate in milli seconds. */
    private long probeRate = HM_PROBE_RATE_DEFAULT;

    /** Enable/Disable greedy learning of IPv6 link local address. */
    private boolean greedyLearningIpv6 = HM_GREEDY_LEARNING_IPV6_DEFAULT;

    /** Enable/Disable tracking of rogue host moves. */
    private boolean hostMoveTrackerEnabled = HM_HOST_MOVE_TRACKER_ENABLE_DEFAULT;

    /** Host move threshold in milli seconds. */
    private int hostMoveThresholdInMillis = HM_HOST_MOVED_THRESHOLD_IN_MILLIS_DEFAULT;

    /** If the host move happening within given threshold then increment the host move counter. */
    private int hostMoveCounter = HM_HOST_MOVE_COUNTER_DEFAULT;

    /** Max value of the counter after which the host will not be considered as offending host. */
    private long offendingHostExpiryInMins = HM_OFFENDING_HOST_EXPIRY_IN_MINS_DEFAULT;

    /** Default pool size of offending host clear executor thread. */
    private int offendingHostClearThreadPool = HM_OFFENDING_HOST_THREADS_POOL_SIZE_DEFAULT;

    private HostMonitor monitor;
    private HostAnnotationOperator hostAnnotationOperator;
    private ScheduledExecutorService offendingHostUnblockExecutor = null;
    private Map<HostId, HostMoveTracker> hostMoveTracker = new ConcurrentHashMap<>();


    @Activate
    public void activate(ComponentContext context) {
        hostAnnotationOperator = new HostAnnotationOperator(networkConfigService);
        store.setDelegate(delegate);
        eventDispatcher.addSink(HostEvent.class, listenerRegistry);
        cfgService.registerProperties(getClass());
        networkConfigService.addListener(networkConfigListener);
        monitor = new HostMonitor(packetService, this, interfaceService, edgePortService);
        monitor.setProbeRate(probeRate);
        monitor.start();
        cfgService.registerProperties(getClass());
        modified(context);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        store.unsetDelegate(delegate);
        eventDispatcher.removeSink(HostEvent.class);
        networkConfigService.removeListener(networkConfigListener);
        cfgService.unregisterProperties(getClass(), false);
        monitor.shutdown();
        if (offendingHostUnblockExecutor != null) {
            offendingHostUnblockExecutor.shutdown();
        }
        log.info("Stopped");
    }

    @Modified
    public void modified(ComponentContext context) {
        boolean oldValue = monitorHosts;
        readComponentConfiguration(context);
        if (probeRate > 0) {
            monitor.setProbeRate(probeRate);
        } else {
            log.warn("ProbeRate cannot be less than 0");
        }

        if (oldValue != monitorHosts) {
            if (monitorHosts) {
                startMonitoring();
            } else {
                stopMonitoring();
            }
        }
    }

    /**
     * Extracts properties from the component configuration context.
     *
     * @param context the component context
     */
    private void readComponentConfiguration(ComponentContext context) {
        Dictionary<?, ?> properties = context.getProperties();
        Boolean flag;
        int newHostMoveThresholdInMillis;
        int newHostMoveCounter;
        int newOffendinghostPoolSize;
        long newOffendingHostExpiryInMins;

        flag = Tools.isPropertyEnabled(properties, HM_MONITOR_HOSTS);
        if (flag == null) {
            log.info("monitorHosts is not enabled " +
                             "using current value of {}", monitorHosts);
        } else {
            monitorHosts = flag;
            log.info("Configured. monitorHosts {}",
                     monitorHosts ? "enabled" : "disabled");
        }

        Long longValue = Tools.getLongProperty(properties, HM_PROBE_RATE);
        if (longValue == null || longValue == 0) {
            log.info("probeRate is not set sing default value of {}", probeRate);
        } else {
            probeRate = longValue;
            log.info("Configured. probeRate {}", probeRate);
        }

        flag = Tools.isPropertyEnabled(properties, HM_ALLOW_DUPLICATE_IPS);
        if (flag == null) {
            log.info("Removal of duplicate ip address is not configured");
        } else {
            allowDuplicateIps = flag;
            log.info("Removal of duplicate ip address is {}",
                     allowDuplicateIps ? "disabled" : "enabled");
        }

        flag = Tools.isPropertyEnabled(properties, HM_GREEDY_LEARNING_IPV6);
        if (flag == null) {
            log.info("greedy learning is not enabled " +
                             "using current value of {}", greedyLearningIpv6);
        } else {
            greedyLearningIpv6 = flag;
            log.info("Configured. greedyLearningIpv6 {}",
                     greedyLearningIpv6 ? "enabled" : "disabled");
        }
        flag = Tools.isPropertyEnabled(properties, HM_HOST_MOVE_TRACKER_ENABLE);
        if (flag == null) {
            log.info("Host move tracker is not configured " +
                    "using current value of {}", hostMoveTrackerEnabled);
        } else {
            hostMoveTrackerEnabled = flag;
            log.info("Configured. hostMoveTrackerEnabled {}",
                    hostMoveTrackerEnabled ? "enabled" : "disabled");

            //On enable cfg ,sets default configuration vales added , else use the default values
            properties = context.getProperties();
            try {
                String s = get(properties, HM_HOST_MOVED_THRESHOLD_IN_MILLIS);
                newHostMoveThresholdInMillis = isNullOrEmpty(s) ?
                        hostMoveThresholdInMillis : Integer.parseInt(s.trim());

                s = get(properties, HM_HOST_MOVE_COUNTER);
                newHostMoveCounter = isNullOrEmpty(s) ? hostMoveCounter : Integer.parseInt(s.trim());

                s = get(properties, HM_OFFENDING_HOST_EXPIRY_IN_MINS);
                newOffendingHostExpiryInMins = isNullOrEmpty(s) ?
                        offendingHostExpiryInMins : Integer.parseInt(s.trim());

                s = get(properties, HM_OFFENDING_HOST_THREADS_POOL_SIZE);
                newOffendinghostPoolSize = isNullOrEmpty(s) ?
                        offendingHostClearThreadPool : Integer.parseInt(s.trim());
            } catch (NumberFormatException | ClassCastException e) {
                newHostMoveThresholdInMillis = HM_HOST_MOVED_THRESHOLD_IN_MILLIS_DEFAULT;
                newHostMoveCounter = HM_HOST_MOVE_COUNTER_DEFAULT;
                newOffendingHostExpiryInMins = HM_OFFENDING_HOST_EXPIRY_IN_MINS_DEFAULT;
                newOffendinghostPoolSize = HM_OFFENDING_HOST_THREADS_POOL_SIZE_DEFAULT;
            }
            if (newHostMoveThresholdInMillis != hostMoveThresholdInMillis) {
                hostMoveThresholdInMillis = newHostMoveThresholdInMillis;
            }
            if (newHostMoveCounter != hostMoveCounter) {
                hostMoveCounter = newHostMoveCounter;
            }
            if (newOffendingHostExpiryInMins != offendingHostExpiryInMins) {
                offendingHostExpiryInMins = newOffendingHostExpiryInMins;
            }
            if (hostMoveTrackerEnabled && offendingHostUnblockExecutor == null) {
                setupThreadPool();
            } else if (newOffendinghostPoolSize != offendingHostClearThreadPool
                    && offendingHostUnblockExecutor != null) {
                offendingHostClearThreadPool = newOffendinghostPoolSize;
                offendingHostUnblockExecutor.shutdown();
                offendingHostUnblockExecutor = null;
                setupThreadPool();
            } else if (!hostMoveTrackerEnabled && offendingHostUnblockExecutor != null) {
                offendingHostUnblockExecutor.shutdown();
                offendingHostUnblockExecutor = null;
            }
            if (newOffendinghostPoolSize != offendingHostClearThreadPool) {
                offendingHostClearThreadPool = newOffendinghostPoolSize;
            }

            log.debug("modified hostMoveThresholdInMillis: {}, hostMoveCounter: {}, " +
                            "offendingHostExpiryInMins: {} ", hostMoveThresholdInMillis,
                    hostMoveCounter, offendingHostExpiryInMins);
        }
    }

    private synchronized void setupThreadPool() {
        offendingHostUnblockExecutor = Executors.newScheduledThreadPool(offendingHostClearThreadPool);
    }

    /**
     * Starts monitoring the hosts by IP Address.
     */
    private void startMonitoring() {
        store.getHosts().forEach(host -> {
            host.ipAddresses().forEach(ip -> {
                monitor.addMonitoringFor(ip);
            });
        });
    }

    /**
     * Stops monitoring the hosts by IP Address.
     */
    private void stopMonitoring() {
        store.getHosts().forEach(host -> {
            host.ipAddresses().forEach(ip -> {
                monitor.stopMonitoring(ip);
            });
        });
    }

    @Override
    protected HostProviderService createProviderService(HostProvider provider) {
        monitor.registerHostProvider(provider);
        return new InternalHostProviderService(provider);
    }

    @Override
    public int getHostCount() {
        checkPermission(HOST_READ);
        return store.getHostCount();
    }

    @Override
    public Iterable<Host> getHosts() {
        checkPermission(HOST_READ);
        return store.getHosts();
    }

    @Override
    public Host getHost(HostId hostId) {
        checkPermission(HOST_READ);
        checkNotNull(hostId, HOST_ID_NULL);
        return store.getHost(hostId);
    }

    @Override
    public Set<Host> getHostsByVlan(VlanId vlanId) {
        checkPermission(HOST_READ);
        return store.getHosts(vlanId);
    }

    @Override
    public Set<Host> getHostsByMac(MacAddress mac) {
        checkPermission(HOST_READ);
        checkNotNull(mac, "MAC address cannot be null");
        return store.getHosts(mac);
    }

    @Override
    public Set<Host> getHostsByIp(IpAddress ip) {
        checkPermission(HOST_READ);
        checkNotNull(ip, "IP address cannot be null");
        return store.getHosts(ip);
    }

    @Override
    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
        checkPermission(HOST_READ);
        checkNotNull(connectPoint, "Connection point cannot be null");
        return store.getConnectedHosts(connectPoint);
    }

    @Override
    public Set<Host> getConnectedHosts(DeviceId deviceId) {
        checkPermission(HOST_READ);
        checkNotNull(deviceId, "Device ID cannot be null");
        return store.getConnectedHosts(deviceId);
    }

    @Override
    public void startMonitoringIp(IpAddress ip) {
        checkPermission(HOST_EVENT);
        monitor.addMonitoringFor(ip);
    }

    @Override
    public void stopMonitoringIp(IpAddress ip) {
        checkPermission(HOST_EVENT);
        monitor.stopMonitoring(ip);
    }

    @Override
    public void requestMac(IpAddress ip) {
        // FIXME!!!! Auto-generated method stub
    }

    @Override
    public void removeHost(HostId hostId) {
        checkNotNull(hostId, HOST_ID_NULL);
        store.removeHost(hostId);
    }

    // Personalized host provider service issued to the supplied provider.
    private class InternalHostProviderService
            extends AbstractProviderService<HostProvider>
            implements HostProviderService {
        InternalHostProviderService(HostProvider provider) {
            super(provider);
        }

        @Override
        public void hostDetected(HostId hostId, HostDescription initialHostDescription, boolean replaceIps) {
            HostDescription hostDescription = initialHostDescription;
            checkNotNull(hostId, HOST_ID_NULL);
            checkValidity();
            hostDescription = validateHost(hostDescription, hostId);

            if (!allowDuplicateIps) {
                removeDuplicates(hostId, hostDescription);
            }

            BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class);
            if (!isAllowed(cfg)) {
                log.warn("Host {} is not allowed to be added into the contol domain", hostId);
                return;
            }

            hostDescription = BasicHostOperator.combine(cfg, initialHostDescription);
            HostAnnotationConfig annoConfig = networkConfigService.getConfig(hostId, HostAnnotationConfig.class);
            if (annoConfig != null) {
                hostDescription = hostAnnotationOperator.combine(hostId, hostDescription, Optional.of(annoConfig));
            }

            if (!hostMoveTrackerEnabled) {
                store.createOrUpdateHost(provider().id(), hostId,
                        hostDescription, replaceIps);
            } else if (!shouldBlock(hostId, hostDescription.locations())) {
                log.debug("Host move is allowed for host with Id: {} ", hostId);
                store.createOrUpdateHost(provider().id(), hostId,
                        hostDescription, replaceIps);
            } else {
                log.info("Host move is NOT allowed for host with Id: {} , removing from host store ", hostId);
            }

            if (monitorHosts) {
                hostDescription.ipAddress().forEach(ip -> {
                    monitor.addMonitoringFor(ip);
                });
            }

            // Greedy learning of IPv6 host. We have to disable the greedy
            // learning of configured hosts. Validate hosts each time will
            // overwrite the learnt information with the configured information.
            if (greedyLearningIpv6) {
                // Auto-generation of the IPv6 link local address
                // using the mac address
                Ip6Address targetIp6Address = Ip6Address.valueOf(
                        getLinkLocalAddress(hostId.mac().toBytes())
                );
                // If we already know this guy we don't need to do other
                if (!hostDescription.ipAddress().contains(targetIp6Address)) {
                    Host host = store.getHost(hostId);
                    // Configured host, skip it.
                    if (host != null && host.configured()) {
                        return;
                    }
                    // Host does not exist in the store or the target is not known
                    if ((host == null || !host.ipAddresses().contains(targetIp6Address))) {
                        // Use DAD to probe if interface MAC is not specified
                        MacAddress probeMac = interfaceService.getInterfacesByPort(hostDescription.location())
                                .stream().map(Interface::mac).findFirst().orElse(MacAddress.ONOS);
                        Ip6Address probeIp = !probeMac.equals(MacAddress.ONOS) ?
                                Ip6Address.valueOf(getLinkLocalAddress(probeMac.toBytes())) :
                                Ip6Address.ZERO;
                        // We send a probe using the monitoring service
                        monitor.sendProbe(
                                hostDescription.location(),
                                targetIp6Address,
                                probeIp,
                                probeMac,
                                hostId.vlanId()
                        );
                    }
                }
            }
        }

        // When a new IP is detected, remove that IP on other hosts if it exists
        public void removeDuplicates(HostId hostId, HostDescription desc) {
            desc.ipAddress().forEach(ip -> {
                Set<Host> allHosts = store.getHosts(ip);
                allHosts.forEach(eachHost -> {
                    if (!(eachHost.id().equals(hostId))) {
                        log.info("Duplicate ip {} found on host {} and {}", ip,
                                hostId.toString(), eachHost.id().toString());
                        store.removeIp(eachHost.id(), ip);
                    }
                });
            });
        }

        // returns a HostDescription made from the union of the BasicHostConfig
        // annotations if it exists
        private HostDescription validateHost(HostDescription hostDescription, HostId hostId) {
            BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class);
            checkState(cfg == null || cfg.isAllowed(), "Host {} is not allowed", hostId);

            return BasicHostOperator.combine(cfg, hostDescription);
        }

        @Override
        public void hostVanished(HostId hostId) {
            checkNotNull(hostId, HOST_ID_NULL);
            checkValidity();
            Host host = store.getHost(hostId);

            if (!allowedToChange(hostId)) {
                log.info("Request to remove {} is ignored due to provider mismatch", hostId);
                return;
            }

            if (monitorHosts) {
                host.ipAddresses().forEach(ip -> {
                    monitor.stopMonitoring(ip);
                });
            }
            store.removeHost(hostId);
        }

        @Override
        public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
            checkNotNull(hostId, HOST_ID_NULL);
            checkValidity();

            if (!allowedToChange(hostId)) {
                log.info("Request to remove {} from {} is ignored due to provider mismatch",
                        ipAddress, hostId);
                return;
            }

            store.removeIp(hostId, ipAddress);
        }

        @Override
        public void addLocationToHost(HostId hostId, HostLocation location) {
            checkNotNull(hostId, HOST_ID_NULL);
            checkValidity();

            if (!allowedToChange(hostId)) {
                log.info("Request to add {} to {} is ignored due to provider mismatch",
                        location, hostId);
                return;
            }

            store.appendLocation(hostId, location);
        }

        @Override
        public void removeLocationFromHost(HostId hostId, HostLocation location) {
            checkNotNull(hostId, HOST_ID_NULL);
            checkValidity();

            if (!allowedToChange(hostId)) {
                log.info("Request to remove {} from {} is ignored due to provider mismatch",
                        location, hostId);
                return;
            }

            store.removeLocation(hostId, location);
        }

        /**
         * Providers should only be able to remove a host that is provided by itself,
         * or a host that is not configured.
         */
        private boolean allowedToChange(HostId hostId) {
            Host host = store.getHost(hostId);
            return host == null || !host.configured() || host.providerId().equals(provider().id());
        }


        /**
         * Deny host move if happening within the threshold time,
         * track moved host to identify offending hosts.
         *
         * @param hostId    host identifier
         * @param locations host locations
         */
        private boolean shouldBlock(HostId hostId, Set<HostLocation> locations) {
            Host host = store.getHost(hostId);
            // If host is not present in host store means host added for hte first time.
            if (host != null) {
                if (host.suspended()) {
                    // Checks host is marked as offending in other onos cluster instance/local instance
                    log.debug("Host id {} is moving frequently hence host moving " +
                            "processing is ignored", hostId);
                    return true;
                }
            } else {
                //host added for the first time.
                return false;
            }
            HostMoveTracker hostMove = hostMoveTracker.computeIfAbsent(hostId, id -> new HostMoveTracker(locations));
            if (Sets.difference(hostMove.getLocations(), locations).isEmpty() &&
                    Sets.difference(locations, hostMove.getLocations()).isEmpty()) {
                log.debug("Not hostmove scenario: Host id: {}, Old Host Location: {}, New host Location: {}",
                        hostId, hostMove.getLocations(), locations);
                return false; // It is not a host move scenario
            } else if (hostMove.getCounter() >= hostMoveCounter && System.currentTimeMillis() - hostMove.getTimeStamp()
                    < hostMoveThresholdInMillis) {
                //Check host move is crossed the threshold, then to mark as offending Host
                log.debug("Host id {} is identified as offending host and entry is added in cache", hostId);
                hostMove.resetHostMoveTracker(locations);
                store.suspend(hostId);
                //Set host suspended flag to false after given offendingHostExpiryInMins
                offendingHostUnblockExecutor.schedule(new UnblockOffendingHost(hostId),
                        offendingHostExpiryInMins,
                        TimeUnit.MINUTES);
                return true;
            } else if (System.currentTimeMillis() - hostMove.getTimeStamp()
                    < hostMoveThresholdInMillis) {
                //Increment the host move count as hostmove occured within the hostMoveThresholdInMillis time
                hostMove.updateHostMoveTracker(locations);
                log.debug("Updated the tracker with the host move registered for host: {}", hostId);
            } else if (System.currentTimeMillis() - hostMove.getTimeStamp()
                    > hostMoveThresholdInMillis) {
                //Hostmove is happened after hostMoveThresholdInMillis time so remove from host tracker.
                hostMove.resetHostMoveTracker(locations);
                store.unsuspend(hostId);
                log.debug("Reset the tracker with the host move registered for host: {}", hostId);
            }
            return false;
        }

        // Set host suspended flag to false after given offendingHostExpiryInMins.
        private final class UnblockOffendingHost implements Runnable {
            private HostId hostId;

            UnblockOffendingHost(HostId hostId) {
                this.hostId = hostId;
            }

            @Override
            public void run() {
                // Set the host suspended flag to false
                try {
                    store.unsuspend(hostId);
                    log.debug("Host {}: Marked host as unsuspended", hostId);
                } catch (Exception ex) {
                    log.debug("Host {}: not present in host list", hostId);
                }
            }
        }
    }


    // Store delegate to re-post events emitted from the store.
    private class InternalStoreDelegate implements HostStoreDelegate {
        @Override
        public void notify(HostEvent event) {
            post(event);
        }
    }

    // listens for NetworkConfigEvents of type BasicHostConfig and removes
    // links that the config does not allow
    private class InternalNetworkConfigListener implements NetworkConfigListener {
        @Override
        public boolean isRelevant(NetworkConfigEvent event) {
            return (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED
                    || event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)
                    && (event.configClass().equals(BasicHostConfig.class)
                    || event.configClass().equals(HostAnnotationConfig.class));
        }

        @Override
        public void event(NetworkConfigEvent event) {
            log.debug("Detected host network config event {}", event.type());
            HostEvent he = null;

            HostId hostId = (HostId) event.subject();
            BasicHostConfig cfg =
                    networkConfigService.getConfig(hostId, BasicHostConfig.class);

            if (!isAllowed(cfg)) {
                kickOutBadHost(hostId);
            } else if (event.configClass().equals(BasicHostConfig.class)) {
                Host host = getHost(hostId);
                HostDescription desc =
                        (host == null) ? null : BasicHostOperator.descriptionOf(host);
                desc = BasicHostOperator.combine(cfg, desc);
                if (desc != null) {
                    he = store.createOrUpdateHost(host.providerId(), hostId, desc, false);
                }
            } else if (event.configClass().equals(HostAnnotationConfig.class)) {
                Host host = getHost(hostId);
                HostProvider hp = (host == null) ? null : getProvider(host.providerId());
                HostDescription desc = (host == null) ? null : BasicHostOperator.descriptionOf(host);
                Optional<Config> prevConfig = event.prevConfig();
                log.debug("Host annotations: {} prevconfig {} desc {}", hostId, prevConfig, desc);
                desc = hostAnnotationOperator.combine(hostId, desc, prevConfig);
                if (desc != null && hp != null) {
                    log.debug("Host annotations update - updated host description :{}", desc.toString());
                    he = store.createOrUpdateHost(hp.id(), hostId, desc, false);
                    if (he != null && he.subject() != null) {
                        log.debug("Host annotations update - Host Event : {}", he.subject().annotations());
                    }
                }
            }

            if (he != null) {
                post(he);
            }
        }
    }

    // by default allowed, otherwise check flag
    private boolean isAllowed(BasicHostConfig cfg) {
        return (cfg == null || cfg.isAllowed());
    }

    // removes the specified host, if it exists
    private void kickOutBadHost(HostId hostId) {
        Host badHost = getHost(hostId);
        if (badHost != null) {
            removeHost(hostId);
        }
    }
}
