/*
 * Copyright 2016-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.pim.impl;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
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.util.SafeRecurringTask;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceEvent;
import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;

import org.onosproject.net.Host;

import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.host.HostService;
import org.onosproject.net.mcast.McastEvent;
import org.onosproject.net.mcast.McastListener;
import org.onosproject.net.mcast.McastRoute;
import org.onosproject.net.mcast.MulticastRouteService;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
import org.slf4j.Logger;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Manages PIMInterfaces.
 *
 * TODO: Do we need to add a ServiceListener?
 */
@Component(immediate = true)
@Service
public class PimInterfaceManager implements PimInterfaceService {

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

    private static final Class<PimInterfaceConfig> PIM_INTERFACE_CONFIG_CLASS = PimInterfaceConfig.class;
    private static final String PIM_INTERFACE_CONFIG_KEY = "pimInterface";

    public static final int DEFAULT_HELLO_INTERVAL = 30; // seconds

    private static final int DEFAULT_TASK_PERIOD_MS = 250;

    // Create a Scheduled Executor service for recurring tasks
    private final ScheduledExecutorService scheduledExecutorService =
            Executors.newScheduledThreadPool(1);

    private final long initialHelloDelay = 1000;

    private final long pimHelloPeriod = DEFAULT_TASK_PERIOD_MS;

    private final int timeoutTaskPeriod = DEFAULT_TASK_PERIOD_MS;

    private final int joinTaskPeriod = 10000;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigRegistry networkConfig;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MulticastRouteService multicastRouteService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected RoutingService unicastRoutingService;

    // Store PIM Interfaces in a map key'd by ConnectPoint
    private final Map<ConnectPoint, PimInterface> pimInterfaces = Maps.newConcurrentMap();

    private final Map<McastRoute, PimInterface> routes = Maps.newConcurrentMap();

    private final InternalNetworkConfigListener configListener =
            new InternalNetworkConfigListener();
    private final InternalInterfaceListener interfaceListener =
            new InternalInterfaceListener();
    private final InternalMulticastListener multicastListener =
            new InternalMulticastListener();

    private final ConfigFactory<ConnectPoint, PimInterfaceConfig> pimConfigFactory
            = new ConfigFactory<ConnectPoint, PimInterfaceConfig>(
            SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY, PIM_INTERFACE_CONFIG_CLASS,
            PIM_INTERFACE_CONFIG_KEY) {

        @Override
        public PimInterfaceConfig createConfig() {
            return new PimInterfaceConfig();
        }
    };

    @Activate
    public void activate() {
        networkConfig.registerConfigFactory(pimConfigFactory);

        // Create PIM Interfaces for each of the existing configured interfaces.
        Set<ConnectPoint> subjects = networkConfig.getSubjects(
                ConnectPoint.class, PIM_INTERFACE_CONFIG_CLASS);
        for (ConnectPoint cp : subjects) {
            PimInterfaceConfig config = networkConfig.getConfig(cp, PIM_INTERFACE_CONFIG_CLASS);
            updateInterface(config);
        }

        networkConfig.addListener(configListener);
        interfaceService.addListener(interfaceListener);
        multicastRouteService.addListener(multicastListener);

        multicastRouteService.getRoutes().forEach(this::addRoute);

        // Schedule the periodic hello sender.
        scheduledExecutorService.scheduleAtFixedRate(
                SafeRecurringTask.wrap(
                        () -> pimInterfaces.values().forEach(PimInterface::sendHello)),
                initialHelloDelay, pimHelloPeriod, TimeUnit.MILLISECONDS);

        // Schedule task to periodically time out expired neighbors
        scheduledExecutorService.scheduleAtFixedRate(
                SafeRecurringTask.wrap(
                        () -> pimInterfaces.values().forEach(PimInterface::checkNeighborTimeouts)),
                0, timeoutTaskPeriod, TimeUnit.MILLISECONDS);

        scheduledExecutorService.scheduleAtFixedRate(
                SafeRecurringTask.wrap(
                        () -> pimInterfaces.values().forEach(PimInterface::sendJoins)),
                0, joinTaskPeriod, TimeUnit.MILLISECONDS);

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        interfaceService.removeListener(interfaceListener);
        networkConfig.removeListener(configListener);
        multicastRouteService.removeListener(multicastListener);
        networkConfig.unregisterConfigFactory(pimConfigFactory);

        // Shutdown the periodic hello task.
        scheduledExecutorService.shutdown();

        log.info("Stopped");
    }

    @Override
    public PimInterface getPimInterface(ConnectPoint cp) {
        PimInterface pi = pimInterfaces.get(cp);
        if (pi == null && log.isTraceEnabled()) {
            log.trace("We have been asked for an Interface we don't have: {}", cp);
        }
        return pi;
    }

    @Override
    public Set<PimInterface> getPimInterfaces() {
        return ImmutableSet.copyOf(pimInterfaces.values());
    }

    private void updateInterface(PimInterfaceConfig config) {
        ConnectPoint cp = config.subject();

        if (!config.isEnabled()) {
            removeInterface(cp);
            return;
        }

        String intfName = config.getInterfaceName();
        Interface intf = interfaceService.getInterfaceByName(cp, intfName);

        if (intf == null) {
            log.debug("Interface configuration missing: {}", config.getInterfaceName());
            return;
        }


        log.debug("Updating Interface for " + intf.connectPoint().toString());
        pimInterfaces.computeIfAbsent(cp, k -> buildPimInterface(config, intf));
    }

    private void removeInterface(ConnectPoint cp) {
        pimInterfaces.remove(cp);
    }

    private PimInterface buildPimInterface(PimInterfaceConfig config, Interface intf) {
        PimInterface.Builder builder = PimInterface.builder()
                .withPacketService(packetService)
                .withInterface(intf);

        config.getHelloInterval().ifPresent(builder::withHelloInterval);
        config.getHoldTime().ifPresent(builder::withHoldTime);
        config.getPriority().ifPresent(builder::withPriority);
        config.getPropagationDelay().ifPresent(builder::withPropagationDelay);
        config.getOverrideInterval().ifPresent(builder::withOverrideInterval);

        return builder.build();
    }

    private void addRoute(McastRoute route) {
        PimInterface pimInterface = getSourceInterface(route);

        if (pimInterface == null) {
            return;
        }

        routes.put(route, pimInterface);
    }

    private void removeRoute(McastRoute route) {
        PimInterface pimInterface = routes.remove(route);

        if (pimInterface == null) {
            return;
        }

        pimInterface.removeRoute(route);
    }

    private PimInterface getSourceInterface(McastRoute route) {
        RouteEntry routeEntry = unicastRoutingService.getLongestMatchableRouteEntry(route.source());

        if (routeEntry == null) {
            log.warn("No route to source {}", route.source());
            return null;
        }

        Interface intf = interfaceService.getMatchingInterface(routeEntry.nextHop());

        if (intf == null) {
            log.warn("No interface with route to next hop {}", routeEntry.nextHop());
            return null;
        }

        PimInterface pimInterface = pimInterfaces.get(intf.connectPoint());

        if (pimInterface == null) {
            log.warn("PIM is not enabled on interface {}", intf);
            return null;
        }

        Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop());
        Host host = null;
        for (Host h : hosts) {
            if (h.vlan().equals(intf.vlan())) {
                host = h;
            }
        }
        if (host == null) {
            log.warn("Next hop host entry not found: {}", routeEntry.nextHop());
            return null;
        }

        pimInterface.addRoute(route, routeEntry.nextHop(), host.mac());

        return pimInterface;
    }

    /**
     * Listener for network config events.
     */
    private class InternalNetworkConfigListener implements NetworkConfigListener {

        @Override
        public void event(NetworkConfigEvent event) {
            if (event.configClass() != PIM_INTERFACE_CONFIG_CLASS) {
                return;
            }

            switch (event.type()) {
            case CONFIG_REGISTERED:
            case CONFIG_UNREGISTERED:
                break;
            case CONFIG_ADDED:
            case CONFIG_UPDATED:
                ConnectPoint cp = (ConnectPoint) event.subject();
                PimInterfaceConfig config = networkConfig.getConfig(
                        cp, PIM_INTERFACE_CONFIG_CLASS);

                updateInterface(config);
                break;
            case CONFIG_REMOVED:
                removeInterface((ConnectPoint) event.subject());
                break;
            default:
                break;
            }
        }
    }

    /**
     * Listener for interface events.
     */
    private class InternalInterfaceListener implements InterfaceListener {

        @Override
        public void event(InterfaceEvent event) {
            switch (event.type()) {
            case INTERFACE_ADDED:
                PimInterfaceConfig config = networkConfig.getConfig(
                        event.subject().connectPoint(), PIM_INTERFACE_CONFIG_CLASS);

                if (config != null) {
                    updateInterface(config);
                }
                break;
            case INTERFACE_UPDATED:
                break;
            case INTERFACE_REMOVED:
                removeInterface(event.subject().connectPoint());
                break;
            default:
                break;

            }
        }
    }

    /**
     * Listener for multicast route events.
     */
    private class InternalMulticastListener implements McastListener {
        @Override
        public void event(McastEvent event) {
            switch (event.type()) {
            case ROUTE_ADDED:
                addRoute(event.subject().route());
                break;
            case ROUTE_REMOVED:
                removeRoute(event.subject().route());
                break;
            case SOURCE_ADDED:
            case SINK_ADDED:
            case SINK_REMOVED:
            default:
                break;
            }
        }
    }
}
