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

import org.onlab.packet.ipv6.IExtensionHeader;
import org.onlab.packet.ndp.NeighborAdvertisement;
import org.onlab.packet.ndp.NeighborSolicitation;
import org.onlab.packet.ndp.Redirect;
import org.onlab.packet.ndp.RouterAdvertisement;
import org.onlab.packet.ndp.RouterSolicitation;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import static org.onlab.packet.PacketUtils.checkInput;

/**
 * Implements ICMPv6 packet format. (RFC 4443)
 */
public class ICMP6 extends BasePacket {
    public static final byte HEADER_LENGTH = 4; // bytes

    // Type
    /** Destination Unreachable. */
    public static final byte DEST_UNREACH = (byte) 0x01;
    /** Packet Too Big. */
    public static final byte PKT_TOO_BIG = (byte) 0x02;
    /** Time Exceeded. */
    public static final byte TIME_EXCEED = (byte) 0x03;
    /** Parameter Problem. */
    public static final byte PARAM_ERR = (byte) 0x04;
    /** Echo Request. */
    public static final byte ECHO_REQUEST = (byte) 0x80;
    /** Echo Reply. */
    public static final byte ECHO_REPLY = (byte) 0x81;
    /** Multicast Listener Query. */
    public static final byte MCAST_QUERY = (byte) 0x82;
    /** Multicast Listener Report. */
    public static final byte MCAST_REPORT = (byte) 0x83;
    /** Multicast Listener Done. */
    public static final byte MCAST_DONE = (byte) 0x84;
    /** Router Solicitation. */
    public static final byte ROUTER_SOLICITATION = (byte) 0x85;
    /** Router Advertisement. */
    public static final byte ROUTER_ADVERTISEMENT = (byte) 0x86;
    /** Neighbor Solicitation. */
    public static final byte NEIGHBOR_SOLICITATION = (byte) 0x87;
    /** Neighbor Advertisement. */
    public static final byte NEIGHBOR_ADVERTISEMENT = (byte) 0x88;
    /** Redirect Message. */
    public static final byte REDIRECT = (byte) 0x89;

    // Code for DEST_UNREACH
    /** No route to destination. */
    public static final byte NO_ROUTE = (byte) 0x00;
    /** Communication with destination administratively prohibited. */
    public static final byte COMM_PROHIBIT = (byte) 0x01;
    /** Beyond scope of source address. */
    public static final byte BEYOND_SCOPE = (byte) 0x02;
    /** Address unreachable. */
    public static final byte ADDR_UNREACH = (byte) 0x03;
    /** Port unreachable. */
    public static final byte PORT_UNREACH = (byte) 0x04;
    /** Source address failed ingress/egress policy. */
    public static final byte FAIL_POLICY = (byte) 0x05;
    /** Reject route to destination. */
    public static final byte REJECT_ROUTE = (byte) 0x06;
    /** Error in Source Routing Header. */
    public static final byte SRC_ROUTING_HEADER_ERR = (byte) 0x07;

    // Code for TIME_EXCEED
    /** Hop limit exceeded in transit. */
    public static final byte HOP_LIMIT_EXCEED = (byte) 0x00;
    /** Fragment reassembly time exceeded. */
    public static final byte DEFRAG_TIME_EXCEED = (byte) 0x01;

    // Code for PARAM_ERR
    /** Erroneous header field encountered. */
    public static final byte HDR_FIELD_ERR = (byte) 0x00;
    /** Unrecognized Next Header type encountered. */
    public static final byte NEXT_HEADER_ERR = (byte) 0x01;
    /** Unrecognized IPv6 option encountered. */
    public static final byte IPV6_OPT_ERR = (byte) 0x01;

    public static final Map<Byte, Deserializer<? extends IPacket>> TYPE_DESERIALIZER_MAP =
            new HashMap<>();

    static {
        ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.ROUTER_SOLICITATION, RouterSolicitation.deserializer());
        ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.ROUTER_ADVERTISEMENT, RouterAdvertisement.deserializer());
        ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.NEIGHBOR_SOLICITATION, NeighborSolicitation.deserializer());
        ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.deserializer());
        ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.REDIRECT, Redirect.deserializer());
    }

    protected byte icmpType;
    protected byte icmpCode;
    protected short checksum;

    private static final byte[] ZERO_ADDRESS = new byte[Ip6Address.BYTE_LENGTH];

    /**
     * Gets ICMP6 type.
     *
     * @return the ICMP6 type
     */
    public byte getIcmpType() {
        return this.icmpType;
    }

    /**
     * Sets ICMP6 type.
     *
     * @param icmpType the ICMP type to set
     * @return this
     */
    public ICMP6 setIcmpType(final byte icmpType) {
        this.icmpType = icmpType;
        return this;
    }

    /**
     * Gets ICMP6 code.
     *
     * @return the ICMP6 code
     */
    public byte getIcmpCode() {
        return this.icmpCode;
    }

    /**
     * Sets ICMP6 code.
     *
     * @param icmpCode the ICMP6 code to set
     * @return this
     */
    public ICMP6 setIcmpCode(final byte icmpCode) {
        this.icmpCode = icmpCode;
        return this;
    }

    /**
     * Gets checksum.
     *
     * @return the checksum
     */
    public short getChecksum() {
        return this.checksum;
    }

    /**
     * Sets checksum.
     *
     * @param checksum the checksum to set
     * @return this
     */
    public ICMP6 setChecksum(final short checksum) {
        this.checksum = checksum;
        return this;
    }

    @Override
    public byte[] serialize() {
        byte[] payloadData = null;
        if (this.payload != null) {
            this.payload.setParent(this);
            payloadData = this.payload.serialize();
        }

        int payloadLength = 0;
        if (payloadData != null) {
            payloadLength = payloadData.length;
        }

        final byte[] data = new byte[HEADER_LENGTH + payloadLength];
        final ByteBuffer bbData = ByteBuffer.wrap(data);

        // Creating ByteBuffer for checksum calculation
        final byte[] checksumData =
            new byte[IPv6.FIXED_HEADER_LENGTH + HEADER_LENGTH + payloadLength];
        final ByteBuffer bbChecksum = ByteBuffer.wrap(checksumData);

        //
        // Creating IPv6 Pseudo Header for checksum calculation according
        // to RFC 4443 and RFC 2460
        //
        IPv6 ipv6Parent = null;
        for (IPacket p = this.parent; p != null; p = p.getParent()) {
            if (p instanceof IPv6) {
                ipv6Parent = (IPv6) p;
                break;
            }
        }
        if (ipv6Parent != null) {
            bbChecksum.put(ipv6Parent.getSourceAddress());
            bbChecksum.put(ipv6Parent.getDestinationAddress());
        } else {
            // NOTE: IPv6 source and destination addresses unknown. Use zeroes.
            bbChecksum.put(ZERO_ADDRESS);
            bbChecksum.put(ZERO_ADDRESS);
        }
        bbChecksum.putInt(HEADER_LENGTH + payloadLength);
        bbChecksum.put((byte) 0);
        bbChecksum.put((byte) 0);
        bbChecksum.put((byte) 0);
        bbChecksum.put(IPv6.PROTOCOL_ICMP6);
        bbChecksum.put(this.icmpType);
        bbChecksum.put(this.icmpCode);
        bbChecksum.put((byte) 0);
        bbChecksum.put((byte) 0);

        bbData.put(this.icmpType);
        bbData.put(this.icmpCode);
        bbData.putShort(this.checksum);
        if (payloadData != null) {
            bbData.put(payloadData);
            bbChecksum.put(payloadData);
        }

        if (this.parent != null) {
            if (this.parent instanceof IPv6) {
                ((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
            } else if (this.parent instanceof IExtensionHeader) {
                ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
            }
        }

        // compute checksum if needed
        if (this.checksum == 0) {
            bbData.rewind();
            bbChecksum.rewind();
            int accumulation = 0;

            for (int i = 0; i < checksumData.length / 2; ++i) {
                accumulation += 0xffff & bbChecksum.getShort();
            }
            // pad to an even number of shorts
            if (checksumData.length % 2 > 0) {
                accumulation += (bbChecksum.get() & 0xff) << 8;
            }

            accumulation = (accumulation >> 16 & 0xffff)
                    + (accumulation & 0xffff);
            this.checksum = (short) (~accumulation & 0xffff);
            bbData.putShort(2, this.checksum);
        }
        return data;
    }

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        this.icmpType = bb.get();
        this.icmpCode = bb.get();
        this.checksum = bb.getShort();

        Deserializer<? extends IPacket> deserializer;
        if (ICMP6.TYPE_DESERIALIZER_MAP.containsKey(icmpType)) {
            deserializer = TYPE_DESERIALIZER_MAP.get(icmpType);
        } else {
            deserializer = Data.deserializer();
        }
        try {
            this.payload = deserializer.deserialize(data, bb.position(),
                                                     bb.limit() - bb.position());
            this.payload.setParent(this);
        } catch (DeserializationException e) {
            return this;
        }

        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 5807;
        int result = super.hashCode();
        result = prime * result + this.icmpType;
        result = prime * result + this.icmpCode;
        result = prime * result + this.checksum;
        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 ICMP6)) {
            return false;
        }
        final ICMP6 other = (ICMP6) obj;
        if (this.icmpType != other.icmpType) {
            return false;
        }
        if (this.icmpCode != other.icmpCode) {
            return false;
        }
        if (this.checksum != other.checksum) {
            return false;
        }
        return true;
    }

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

            ICMP6 icmp6 = new ICMP6();

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

            icmp6.icmpType = bb.get();
            icmp6.icmpCode = bb.get();
            icmp6.checksum = bb.getShort();

            Deserializer<? extends IPacket> deserializer;
            if (ICMP6.TYPE_DESERIALIZER_MAP.containsKey(icmp6.icmpType)) {
                deserializer = TYPE_DESERIALIZER_MAP.get(icmp6.icmpType);
            } else {
                deserializer = Data.deserializer();
            }
            icmp6.payload = deserializer.deserialize(data, bb.position(),
                                                bb.limit() - bb.position());
            icmp6.payload.setParent(icmp6);

            return icmp6;
        };
    }
}
