/*
 * 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 com.google.common.base.MoreObjects.toStringHelper;
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;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("icmpType", Byte.toString(icmpType))
                .add("icmpCode", Byte.toString(icmpCode))
                .add("checksum", Short.toString(checksum))
                .toString();
    }
}
