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

import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
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.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP6;
import org.onlab.packet.IPv6;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.packet.ndp.NeighborAdvertisement;
import org.onlab.packet.ndp.NeighborDiscoveryOptions;
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.Interface;
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.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.DefaultOutboundPacket;
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.nio.ByteBuffer;
import java.util.Dictionary;
import java.util.List;
import java.util.Objects;

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 NeighbourPacketManager 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 = "ndpEnabled", boolValue = false,
            label = "Enable IPv6 neighbour discovery")
    protected boolean ndpEnabled = false;

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

    private ListMultimap<ConnectPoint, HandlerRegistration> packetHandlers =
            Multimaps.synchronizedListMultimap(LinkedListMultimap.create());

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

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

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

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

        requestPackets();
    }

    private void requestPackets() {
        packetService.requestPackets(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) {
        packetHandlers.put(connectPoint, new HandlerRegistration(handler));
    }

    @Override
    public void registerNeighbourHandler(Interface intf, NeighbourMessageHandler handler) {
        packetHandlers.put(intf.connectPoint(), new HandlerRegistration(handler, intf));
    }

    @Override
    public void unregisterNeighbourHandler(ConnectPoint connectPoint, NeighbourMessageHandler handler) {
        packetHandlers.remove(connectPoint, handler);
    }

    @Override
    public void unregisterNeighbourHandler(Interface intf, NeighbourMessageHandler handler) {
        packetHandlers.remove(intf.connectPoint(), handler);
    }

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

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

        if (msgContext == null) {
            return;
        }

        handleMessage(msgContext);

        context.block();
    }

    private void handleMessage(NeighbourMessageContext context) {
        List<HandlerRegistration> handlers = packetHandlers.get(context.inPort());

        handlers.forEach(registration -> {
            if (registration.intf() == null || matches(context, registration.intf())) {
                registration.handler().handleMessage(context, hostService);
            }
        });
    }

    private boolean matches(NeighbourMessageContext context, Interface intf) {
        checkNotNull(context);
        checkNotNull(intf);

        boolean matches = true;
        if (!intf.vlan().equals(VlanId.NONE) && !intf.vlan().equals(context.vlan())) {
            matches = false;
        }

        return matches;
    }


    private void reply(NeighbourMessageContext context, MacAddress targetMac) {
        switch (context.protocol()) {
        case ARP:
            sendTo(ARP.buildArpReply((Ip4Address) context.target(),
                    targetMac, context.packet()), context.inPort());
            break;
        case NDP:
            sendTo(buildNdpReply((Ip6Address) context.target(), targetMac,
                    context.packet()), context.inPort());
            break;
        default:
            break;
        }
    }

    /**
     * Outputs a packet out a specific port.
     *
     * @param packet  the packet to send
     * @param outPort the port to send it out
     */
    private void sendTo(Ethernet packet, ConnectPoint outPort) {
        sendTo(ByteBuffer.wrap(packet.serialize()), outPort);
    }

    /**
     * Outputs a packet out a specific port.
     *
     * @param packet packet to send
     * @param outPort port to send it out
     */
    private void sendTo(ByteBuffer packet, ConnectPoint outPort) {
        if (!edgeService.isEdgePoint(outPort)) {
            // Sanity check to make sure we don't send the packet out an
            // internal port and create a loop (could happen due to
            // misconfiguration).
            return;
        }

        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
        builder.setOutput(outPort.port());
        packetService.emit(new DefaultOutboundPacket(outPort.deviceId(),
                builder.build(), packet));
    }

    /**
     * Builds an Neighbor Discovery reply based on a request.
     *
     * @param srcIp   the IP address to use as the reply source
     * @param srcMac  the MAC address to use as the reply source
     * @param request the Neighbor Solicitation request we got
     * @return an Ethernet frame containing the Neighbor Advertisement reply
     */
    private Ethernet buildNdpReply(Ip6Address srcIp, MacAddress srcMac,
                                   Ethernet request) {
        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(request.getSourceMAC());
        eth.setSourceMACAddress(srcMac);
        eth.setEtherType(Ethernet.TYPE_IPV6);
        eth.setVlanID(request.getVlanID());

        IPv6 requestIp = (IPv6) request.getPayload();
        IPv6 ipv6 = new IPv6();
        ipv6.setSourceAddress(srcIp.toOctets());
        ipv6.setDestinationAddress(requestIp.getSourceAddress());
        ipv6.setHopLimit((byte) 255);

        ICMP6 icmp6 = new ICMP6();
        icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
        icmp6.setIcmpCode((byte) 0);

        NeighborAdvertisement nadv = new NeighborAdvertisement();
        nadv.setTargetAddress(srcIp.toOctets());
        nadv.setSolicitedFlag((byte) 1);
        nadv.setOverrideFlag((byte) 1);
        nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
                srcMac.toBytes());

        icmp6.setPayload(nadv);
        ipv6.setPayload(icmp6);
        eth.setPayload(ipv6);
        return eth;
    }

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

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

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

        /**
         * Gets the interface of the registration.
         *
         * @return interface
         */
        public Interface intf() {
            return intf;
        }

        /**
         * Gets the neighbour message handler.
         *
         * @return message handler
         */
        public NeighbourMessageHandler handler() {
            return handler;
        }

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

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

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

    private class InternalNeighbourMessageActions implements NeighbourMessageActions {

        @Override
        public void reply(NeighbourMessageContext context, MacAddress targetMac) {
            NeighbourPacketManager.this.reply(context, targetMac);
        }

        @Override
        public void proxy(NeighbourMessageContext context, ConnectPoint outPort) {
            sendTo(context.packet(), outPort);
        }

        @Override
        public void proxy(NeighbourMessageContext context, Interface outIntf) {

        }

        @Override
        public void flood(NeighbourMessageContext context) {
            edgeService.getEdgePoints().forEach(connectPoint -> {
                if (!connectPoint.equals(context.inPort())) {
                    sendTo(context.packet(), connectPoint);
                }
            });
        }

        @Override
        public void drop(NeighbourMessageContext context) {

        }
    }

}
