/*
 * Copyright 2016-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.incubator.net.neighbour.impl;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
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.Modified;
import org.apache.felix.scr.annotations.Property;
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.Ethernet;
import org.onlab.packet.ICMP6;
import org.onlab.packet.IPv6;
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.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.intf.Interface;
import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
import org.onosproject.incubator.net.neighbour.NeighbourMessageActions;
import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.packet.Ethernet.TYPE_ARP;
import static org.onlab.packet.Ethernet.TYPE_IPV6;
import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
import static org.onosproject.net.packet.PacketPriority.CONTROL;

/**
 * Manages handlers for neighbour messages.
 */
@Service
@Component(immediate = true)
public class NeighbourResolutionManager implements NeighbourResolutionService {

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected EdgePortService edgeService;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ComponentConfigService componentConfigService;

    @Property(name = "arpEnabled", boolValue = true,
            label = "Enable Address resolution protocol")
    protected boolean arpEnabled = true;

    @Property(name = "ndpEnabled", boolValue = false,
            label = "Enable IPv6 neighbour discovery")
    protected boolean ndpEnabled = false;

    @Property(name = "requestInterceptsEnabled", boolValue = true,
            label = "Enable requesting packet intercepts")
    private boolean requestInterceptsEnabled = true;

    private static final String APP_NAME = "org.onosproject.neighbour";
    private ApplicationId appId;

    private final SetMultimap<ConnectPoint, NeighbourHandlerRegistration> packetHandlers =
            Multimaps.synchronizedSetMultimap(HashMultimap.create());

    private final InternalPacketProcessor processor = new InternalPacketProcessor();
    private NeighbourMessageActions actions;

    @Activate
    protected void activate(ComponentContext context) {
        appId = coreService.registerApplication(APP_NAME);

        componentConfigService.registerProperties(getClass());
        modified(context);

        actions = new DefaultNeighbourMessageActions(packetService, edgeService);

        packetService.addProcessor(processor, PacketProcessor.director(1));
    }

    @Deactivate
    protected void deactivate() {
        cancelPackets();
        packetService.removeProcessor(processor);
        componentConfigService.unregisterProperties(getClass(), false);
    }

    @Modified
    protected void modified(ComponentContext context) {
        Dictionary<?, ?> properties = context.getProperties();
        Boolean flag;

        flag = Tools.isPropertyEnabled(properties, "ndpEnabled");
        if (flag != null) {
            ndpEnabled = flag;
            log.info("IPv6 neighbor discovery is {}",
                    ndpEnabled ? "enabled" : "disabled");
        }

        flag = Tools.isPropertyEnabled(properties, "arpEnabled");
        if (flag != null) {
            arpEnabled = flag;
            log.info("Address resolution protocol is {}",
                     arpEnabled ? "enabled" : "disabled");
        }

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

        synchronized (packetHandlers) {
            if (!packetHandlers.isEmpty() && requestInterceptsEnabled) {
                requestPackets();
            } else {
                cancelPackets();
            }
        }
    }

    private void requestPackets() {
        if (arpEnabled) {
            packetService.requestPackets(buildArpSelector(), CONTROL, appId);
        } else {
            packetService.cancelPackets(buildArpSelector(), CONTROL, appId);
        }

        if (ndpEnabled) {
            packetService.requestPackets(buildNeighborSolicitationSelector(),
                    CONTROL, appId);
            packetService.requestPackets(buildNeighborAdvertisementSelector(),
                    CONTROL, appId);
        } else {
            packetService.cancelPackets(buildNeighborSolicitationSelector(),
                    CONTROL, appId);
            packetService.cancelPackets(buildNeighborAdvertisementSelector(),
                    CONTROL, appId);
        }
    }

    private void cancelPackets() {
        packetService.cancelPackets(buildArpSelector(), CONTROL, appId);
        packetService.cancelPackets(buildNeighborSolicitationSelector(),
                CONTROL, appId);
        packetService.cancelPackets(buildNeighborAdvertisementSelector(),
                CONTROL, appId);
    }

    private TrafficSelector buildArpSelector() {
        return DefaultTrafficSelector.builder()
                .matchEthType(TYPE_ARP)
                .build();
    }

    private TrafficSelector buildNeighborSolicitationSelector() {
        return DefaultTrafficSelector.builder()
                .matchEthType(TYPE_IPV6)
                .matchIPProtocol(PROTOCOL_ICMP6)
                .matchIcmpv6Type(NEIGHBOR_SOLICITATION)
                .build();
    }

    private TrafficSelector buildNeighborAdvertisementSelector() {
        return DefaultTrafficSelector.builder()
                .matchEthType(TYPE_IPV6)
                .matchIPProtocol(PROTOCOL_ICMP6)
                .matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT)
                .build();
    }

    @Override
    public void registerNeighbourHandler(ConnectPoint connectPoint,
                                         NeighbourMessageHandler handler,
                                         ApplicationId appId) {
        register(connectPoint, new HandlerRegistration(handler, appId));
    }

    @Override
    public void registerNeighbourHandler(Interface intf,
                                         NeighbourMessageHandler handler,
                                         ApplicationId appId) {
        register(intf.connectPoint(), new HandlerRegistration(handler, intf, appId));
    }

    private void register(ConnectPoint connectPoint, HandlerRegistration registration) {
        synchronized (packetHandlers) {
            if (packetHandlers.isEmpty() && requestInterceptsEnabled) {
                requestPackets();
            }
            packetHandlers.put(connectPoint, registration);
        }
    }

    @Override
    public void unregisterNeighbourHandler(ConnectPoint connectPoint,
                                           NeighbourMessageHandler handler,
                                           ApplicationId appId) {
        unregister(connectPoint, new HandlerRegistration(handler, appId));
    }

    @Override
    public void unregisterNeighbourHandler(Interface intf,
                                           NeighbourMessageHandler handler,
                                           ApplicationId appId) {
        unregister(intf.connectPoint(), new HandlerRegistration(handler, intf, appId));
    }

    private void unregister(ConnectPoint connectPoint, HandlerRegistration registration) {
        synchronized (packetHandlers) {
            packetHandlers.remove(connectPoint, registration);

            if (packetHandlers.isEmpty()) {
                cancelPackets();
            }
        }
    }

    @Override
    public void unregisterNeighbourHandlers(ApplicationId appId) {
        synchronized (packetHandlers) {
            Iterator<NeighbourHandlerRegistration> it = packetHandlers.values().iterator();

            while (it.hasNext()) {
                NeighbourHandlerRegistration registration = it.next();
                if (registration.appId().equals(appId)) {
                    it.remove();
                }
            }

            if (packetHandlers.isEmpty()) {
                cancelPackets();
            }
        }
    }

    @Override
    public Map<ConnectPoint, Collection<NeighbourHandlerRegistration>> getHandlerRegistrations() {
        return ImmutableMap.copyOf(Multimaps.asMap(packetHandlers));
    }

    private void handlePacket(PacketContext context) {
        InboundPacket pkt = context.inPacket();
        Ethernet ethPkt = pkt.parsed();

        NeighbourMessageContext msgContext =
                DefaultNeighbourMessageContext.createContext(ethPkt, pkt.receivedFrom(), actions);

        if (msgContext == null) {
            return;
        }

        if (handleMessage(msgContext)) {
            context.block();
        }

    }

    private boolean handleMessage(NeighbourMessageContext context) {
        Collection<NeighbourHandlerRegistration> handlers = packetHandlers.get(context.inPort());

        Collection<NeighbourHandlerRegistration> handled = handlers
                .stream()
                .filter(registration -> registration.intf() == null || matches(context, registration.intf()))
                .collect(Collectors.toSet());

        handled.forEach(registration -> registration.handler().handleMessage(context, hostService));

        return !handled.isEmpty();

    }

    /**
     * Checks that incoming packet matches the parameters of the interface.
     * This means that if the interface specifies a particular parameter
     * (VLAN, IP address, etc.) then the incoming packet should match those
     * parameters.
     *
     * @param context incoming message context
     * @param intf interface to check
     * @return true if the incoming message matches the interface, otherwise false
     */
    private boolean matches(NeighbourMessageContext context, Interface intf) {
        checkNotNull(context);
        checkNotNull(intf);

        boolean matches = true;
        // For non-broadcast packets, if the interface has a MAC address check that
        // the destination MAC address of the packet matches the interface MAC
        if (!context.dstMac().isBroadcast() &&
                !intf.mac().equals(MacAddress.NONE) &&
                !intf.mac().equals(context.dstMac())) {
            matches = false;
        }
        // If the interface has a VLAN, check that the packet's VLAN matches
        if (!intf.vlan().equals(VlanId.NONE) && !intf.vlan().equals(context.vlan())) {
            matches = false;
        }
        // If the interface has IP addresses, check that the packet's target IP
        // address matches one of the interface IP addresses
        if (!intf.ipAddressesList().isEmpty() && !hasIp(intf, context.target())) {
            matches = false;
        }

        return matches;
    }

    /**
     * Returns true if the interface has the given IP address.
     *
     * @param intf interface to check
     * @param ip IP address
     * @return true if the IP is configured on the interface, otherwise false
     */
    private boolean hasIp(Interface intf, IpAddress ip) {
        return intf.ipAddressesList().stream()
                .anyMatch(intfAddress -> intfAddress.ipAddress().equals(ip));
    }

    /**
     * Stores a neighbour message handler registration.
     */
    private class HandlerRegistration implements NeighbourHandlerRegistration {
        private final Interface intf;
        private final NeighbourMessageHandler handler;
        private final ApplicationId appId;

        /**
         * Creates a new handler registration.
         *
         * @param handler neighbour message handler
         */
        public HandlerRegistration(NeighbourMessageHandler handler, ApplicationId appId) {
            this(handler, null, appId);
        }

        /**
         * Creates a new handler registration.
         *
         * @param handler neighbour message handler
         * @param intf interface
         */
        public HandlerRegistration(NeighbourMessageHandler handler, Interface intf, ApplicationId appId) {
            this.intf = intf;
            this.handler = handler;
            this.appId = appId;
        }

        @Override
        public Interface intf() {
            return intf;
        }

        @Override
        public NeighbourMessageHandler handler() {
            return handler;
        }

        @Override
        public ApplicationId appId() {
            return appId;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }

            if (!(other instanceof HandlerRegistration)) {
                return false;
            }

            HandlerRegistration that = (HandlerRegistration) other;

            return Objects.equals(intf, that.intf) &&
                    Objects.equals(handler, that.handler) &&
                    Objects.equals(appId, that.appId);
        }

        @Override
        public int hashCode() {
            return Objects.hash(intf, handler, appId);
        }
    }

    /**
     * Packet processor for incoming packets.
     */
    private class InternalPacketProcessor implements PacketProcessor {

        @Override
        public void process(PacketContext context) {
            // Stop processing if the packet has been handled, since we
            // can't do any more to it.
            if (context.isHandled()) {
                return;
            }

            InboundPacket pkt = context.inPacket();
            Ethernet ethPkt = pkt.parsed();
            if (ethPkt == null) {
                return;
            }

            if (ethPkt.getEtherType() == TYPE_ARP) {
                // handle ARP packets
                handlePacket(context);
            } else if (ethPkt.getEtherType() == TYPE_IPV6) {
                IPv6 ipv6 = (IPv6) ethPkt.getPayload();
                if (ipv6.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
                    ICMP6 icmp6 = (ICMP6) ipv6.getPayload();
                    if (icmp6.getIcmpType() == NEIGHBOR_SOLICITATION ||
                            icmp6.getIcmpType() == NEIGHBOR_ADVERTISEMENT) {
                        // handle ICMPv6 solicitations and advertisements (NDP)
                        handlePacket(context);
                    }
                }
            }
        }
    }
}
