/*
 * 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.annotations.Beta;
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.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.packet.ndp.NeighborSolicitation;
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.NeighbourMessageType;
import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
import org.onosproject.net.ConnectPoint;

import static com.google.common.base.Preconditions.checkState;

/**
 * Default implementation of a neighbour message context.
 */
@Beta
public class DefaultNeighbourMessageContext implements NeighbourMessageContext {

    private final NeighbourProtocol protocol;
    private final NeighbourMessageType type;

    private final IpAddress target;
    private final IpAddress sender;

    private final Ethernet eth;
    private final ConnectPoint inPort;

    private final NeighbourMessageActions actions;

    /**
     * Creates a new neighbour message context.
     *
     * @param actions actions
     * @param eth ethernet frame
     * @param inPort incoming port
     * @param protocol message protocol
     * @param type message type
     * @param target target IP address
     * @param sender sender IP address
     */
    DefaultNeighbourMessageContext(NeighbourMessageActions actions,
                                   Ethernet eth, ConnectPoint inPort,
                                   NeighbourProtocol protocol,
                                   NeighbourMessageType type,
                                   IpAddress target, IpAddress sender) {
        this.actions = actions;
        this.eth = eth;
        this.inPort = inPort;
        this.protocol = protocol;
        this.type = type;
        this.target = target;
        this.sender = sender;
    }

    @Override
    public ConnectPoint inPort() {
        return inPort;
    }

    @Override
    public Ethernet packet() {
        return eth;
    }

    @Override
    public NeighbourProtocol protocol() {
        return protocol;
    }

    @Override
    public NeighbourMessageType type() {
        return type;
    }

    @Override
    public VlanId vlan() {
        return VlanId.vlanId(eth.getVlanID());
    }

    @Override
    public MacAddress srcMac() {
        return MacAddress.valueOf(eth.getSourceMACAddress());
    }

    @Override
    public IpAddress target() {
        return target;
    }

    @Override
    public IpAddress sender() {
        return sender;
    }

    @Override
    public void proxy(ConnectPoint outPort) {
        actions.proxy(this, outPort);
    }

    @Override
    public void proxy(Interface outIntf) {
        actions.proxy(this, outIntf);
    }

    @Override
    public void reply(MacAddress targetMac) {
        checkState(type == NeighbourMessageType.REQUEST, "can only reply to requests");

        actions.reply(this, targetMac);
    }

    @Override
    public void flood() {
        actions.flood(this);
    }

    @Override
    public void drop() {
        actions.drop(this);
    }

    /**
     * Attempts to create a MessageContext for the given Ethernet frame. If the
     * frame is a valid ARP or NDP request or response, a context will be
     * created.
     *
     * @param eth input Ethernet frame
     * @param inPort in port
     * @return MessageContext if the packet was ARP or NDP, otherwise null
     */
    public static NeighbourMessageContext createContext(Ethernet eth,
                                                        ConnectPoint inPort,
                                                        NeighbourMessageActions actions) {
        if (eth.getEtherType() == Ethernet.TYPE_ARP) {
            return createArpContext(eth, inPort, actions);
        } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
            return createNdpContext(eth, inPort, actions);
        }

        return null;
    }

    /**
     * Extracts context information from ARP packets.
     *
     * @param eth input Ethernet frame that is thought to be ARP
     * @param inPort in port
     * @return MessageContext object if the packet was a valid ARP packet,
     * otherwise null
     */
    private static NeighbourMessageContext createArpContext(Ethernet eth,
                                                            ConnectPoint inPort,
                                                            NeighbourMessageActions actions) {
        if (eth.getEtherType() != Ethernet.TYPE_ARP) {
            return null;
        }

        ARP arp = (ARP) eth.getPayload();

        IpAddress target = Ip4Address.valueOf(arp.getTargetProtocolAddress());
        IpAddress sender = Ip4Address.valueOf(arp.getSenderProtocolAddress());

        NeighbourMessageType type;
        if (arp.getOpCode() == ARP.OP_REQUEST) {
            type = NeighbourMessageType.REQUEST;
        } else if (arp.getOpCode() == ARP.OP_REPLY) {
            type = NeighbourMessageType.REPLY;
        } else {
            return null;
        }

        return new DefaultNeighbourMessageContext(actions, eth, inPort,
                NeighbourProtocol.ARP, type, target, sender);
    }

    /**
     * Extracts context information from NDP packets.
     *
     * @param eth input Ethernet frame that is thought to be NDP
     * @param inPort in port
     * @return MessageContext object if the packet was a valid NDP packet,
     * otherwise null
     */
    private static NeighbourMessageContext createNdpContext(Ethernet eth,
                                                            ConnectPoint inPort,
                                                            NeighbourMessageActions actions) {
        if (eth.getEtherType() != Ethernet.TYPE_IPV6) {
            return null;
        }
        IPv6 ipv6 = (IPv6) eth.getPayload();

        if (ipv6.getNextHeader() != IPv6.PROTOCOL_ICMP6) {
            return null;
        }
        ICMP6 icmpv6 = (ICMP6) ipv6.getPayload();

        IpAddress sender = Ip6Address.valueOf(ipv6.getSourceAddress());
        IpAddress target = null;

        NeighbourMessageType type;
        if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION) {
            type = NeighbourMessageType.REQUEST;
            NeighborSolicitation nsol = (NeighborSolicitation) icmpv6.getPayload();
            target = Ip6Address.valueOf(nsol.getTargetAddress());
        } else if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_ADVERTISEMENT) {
            type = NeighbourMessageType.REPLY;
        } else {
            return null;
        }

        return new DefaultNeighbourMessageContext(actions, eth, inPort,
                NeighbourProtocol.NDP, type, target, sender);
    }

}
