/*
 * Copyright 2015-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.onlab.packet.ndp;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Deserializer;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP6;
import org.onlab.packet.IPv6;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.MacAddress;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.packet.PacketUtils.checkInput;

/**
 * Implements ICMPv6 Neighbor Advertisement packet format (RFC 4861).
 */
public class NeighborAdvertisement extends BasePacket {
    public static final byte HEADER_LENGTH = 20; // bytes
    // Constants for NDP reply
    protected static final byte NDP_HOP_LIMIT = (byte) 0x255;
    protected static final byte NDP_SOLICITED_FLAG = (byte) 0x1;
    protected static final byte NDP_OVERRIDE_FLAG = (byte) 0x1;
    protected static final byte RESERVED_CODE = (byte) 0x0;

    protected byte routerFlag;
    protected byte solicitedFlag;
    protected byte overrideFlag;
    protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];

    private final NeighborDiscoveryOptions options =
        new NeighborDiscoveryOptions();

    /**
     * Gets router flag.
     *
     * @return the router flag
     */
    public byte getRouterFlag() {
        return this.routerFlag;
    }

    /**
     * Sets router flag.
     *
     * @param routerFlag the router flag to set
     * @return this
     */
    public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
        this.routerFlag = routerFlag;
        return this;
    }

    /**
     * Gets solicited flag.
     *
     * @return the solicited flag
     */
    public byte getSolicitedFlag() {
        return this.solicitedFlag;
    }

    /**
     * Sets solicited flag.
     *
     * @param solicitedFlag the solicited flag to set
     * @return this
     */
    public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
        this.solicitedFlag = solicitedFlag;
        return this;
    }

    /**
     * Gets override flag.
     *
     * @return the override flag
     */
    public byte getOverrideFlag() {
        return this.overrideFlag;
    }

    /**
     * Sets override flag.
     *
     * @param overrideFlag the override flag to set
     * @return this
     */
    public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
        this.overrideFlag = overrideFlag;
        return this;
    }

    /**
     * Gets target address.
     *
     * @return the target IPv6 address
     */
    public byte[] getTargetAddress() {
        return this.targetAddress;
    }

    /**
     * Sets target address.
     *
     * @param targetAddress the target IPv6 address to set
     * @return this
     */
    public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
        this.targetAddress =
            Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
        return this;
    }

    /**
     * Gets the Neighbor Discovery Protocol packet options.
     *
     * @return the Neighbor Discovery Protocol packet options
     */
    public List<NeighborDiscoveryOptions.Option> getOptions() {
        return this.options.options();
    }

    /**
     * Adds a Neighbor Discovery Protocol packet option.
     *
     * @param type the option type
     * @param data the option data
     * @return this
     */
    public NeighborAdvertisement addOption(final byte type,
                                           final byte[] data) {
        this.options.addOption(type, data);
        return this;
    }

    @Override
    public byte[] serialize() {
        byte[] optionsData = null;
        if (this.options.hasOptions()) {
            optionsData = this.options.serialize();
        }

        int optionsLength = 0;
        if (optionsData != null) {
            optionsLength = optionsData.length;
        }

        final byte[] data = new byte[HEADER_LENGTH + optionsLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.putInt((this.routerFlag & 0x1) << 31 |
                  (this.solicitedFlag & 0x1) << 30 |
                  (this.overrideFlag & 0x1) << 29);
        bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
        if (optionsData != null) {
            bb.put(optionsData);
        }

        return data;
    }



    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 5807;
        int result = super.hashCode();
        ByteBuffer bb;
        result = prime * result + this.routerFlag;
        result = prime * result + this.solicitedFlag;
        result = prime * result + this.overrideFlag;
        bb = ByteBuffer.wrap(this.targetAddress);
        for (int i = 0; i < this.targetAddress.length / 4; i++) {
            result = prime * result + bb.getInt();
        }
        result = prime * result + this.options.hashCode();
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof NeighborAdvertisement)) {
            return false;
        }
        final NeighborAdvertisement other = (NeighborAdvertisement) obj;
        if (this.routerFlag != other.routerFlag) {
            return false;
        }
        if (this.solicitedFlag != other.solicitedFlag) {
            return false;
        }
        if (this.overrideFlag != other.overrideFlag) {
            return false;
        }
        if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
            return false;
        }
        if (!this.options.equals(other.options)) {
            return false;
        }
        return true;
    }

    /**
     * Deserializer function for neighbor advertisement packets.
     *
     * @return deserializer function
     */
    public static Deserializer<NeighborAdvertisement> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, HEADER_LENGTH);

            NeighborAdvertisement neighborAdvertisement = new NeighborAdvertisement();

            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

            int iscratch;

            iscratch = bb.getInt();
            neighborAdvertisement.routerFlag = (byte) (iscratch >> 31 & 0x1);
            neighborAdvertisement.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
            neighborAdvertisement.overrideFlag = (byte) (iscratch >> 29 & 0x1);
            bb.get(neighborAdvertisement.targetAddress, 0, Ip6Address.BYTE_LENGTH);

            if (bb.limit() - bb.position() > 0) {
                NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
                        .deserialize(data, bb.position(), bb.limit() - bb.position());

                for (NeighborDiscoveryOptions.Option option : options.options()) {
                    neighborAdvertisement.addOption(option.type(), option.data());
                }
            }

            return neighborAdvertisement;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("routerFlag", Byte.toString(routerFlag))
                .add("solicitedFlag", Byte.toString(solicitedFlag))
                .add("overrideFlag", Byte.toString(overrideFlag))
                .add("targetAddress", Arrays.toString(targetAddress))
                .toString();
    }

    /**
     * Builds an NDP 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
     */
    public static Ethernet buildNdpAdv(Ip6Address srcIp,
                                       MacAddress srcMac,
                                       Ethernet request) {

        checkNotNull(srcIp, "IP address cannot be null");
        checkNotNull(srcMac, "MAC address cannot be null");
        checkNotNull(request, "Request cannot be null");
        checkArgument(request.getEtherType() == Ethernet.TYPE_IPV6,
                "EtherType must be IPv6");

        final IPv6 ipv6Request = (IPv6) request.getPayload();

        checkArgument(ipv6Request.getNextHeader() == IPv6.PROTOCOL_ICMP6,
                "Protocol must be ICMP6");

        final ICMP6 icmpv6 = (ICMP6) ipv6Request.getPayload();

        checkArgument(icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION,
                "ICMP6 type must be NEIGHBOR_SOLICITATION");

        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(request.getSourceMAC());
        eth.setSourceMACAddress(srcMac);
        eth.setEtherType(Ethernet.TYPE_IPV6);
        eth.setVlanID(request.getVlanID());

        IPv6 ipv6 = new IPv6();
        ipv6.setSourceAddress(srcIp.toOctets());
        ipv6.setDestinationAddress(ipv6Request.getSourceAddress());
        ipv6.setHopLimit(NDP_HOP_LIMIT);
        ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6);

        ICMP6 icmp6 = new ICMP6();
        icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
        icmp6.setIcmpCode(RESERVED_CODE);

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

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

}
