/*
 * Copyright 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.pim.PIMHello;
import org.onlab.packet.pim.PIMJoinPrune;

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

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

/**
 * Implements PIM control packet format.
 */
public class PIM extends BasePacket {

    public static final IpAddress PIM_ADDRESS = IpAddress.valueOf("224.0.0.13");

    public static final byte TYPE_HELLO = 0x00;
    public static final byte TYPE_REGISTER = 0x01;
    public static final byte TYPE_REQUEST_STOP = 0x02;
    public static final byte TYPE_JOIN_PRUNE_REQUEST = 0x03;
    public static final byte TYPE_BOOTSTRAP = 0x04;
    public static final byte TYPE_ASSERT = 0x05;
    public static final byte TYPE_GRAFT = 0x06;
    public static final byte TYPE_GRAFT_ACK = 0x07;
    public static final byte TYPE_CANDIDATE_RP_ADV = 0x08;

    public static final int PIM_HEADER_LEN = 4;

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

    static {
        PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_HELLO, PIMHello.deserializer());
        PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_JOIN_PRUNE_REQUEST, PIMJoinPrune.deserializer());
    }

    /*
     * PIM Header fields
     */
    protected byte version;
    protected byte type;
    protected byte reserved;
    protected short checksum;

    /**
     * Default constructor.
     */
    public PIM() {
        super();
        this.version = 2;
        this.reserved = 0;
    }

    /**
     * Return the PIM message type.
     *
     * @return the pimMsgType
     */
    public byte getPimMsgType() {
        return this.type;
    }

    /**
     * Set the PIM message type. Currently PIMJoinPrune and PIMHello are
     * supported.
     *
     * @param type PIM message type
     * @return PIM Header
     */
     public PIM setPIMType(final byte type) {
            this.type = type;
            return this;
     }

    /**
     * Get the version of PIM.
     *
     * @return the PIM version.   Must be 2.
     */
    public byte getVersion() {
         return version;
    }

    /**
     * Set the PIM version type. Should not change from 2.
     *
     * @param version PIM version
     */
    public void setVersion(byte version) {
         this.version = version;
    }

    /**
     * Get the reserved field.
     *
     * @return the reserved field.  Must be ignored.
     */
    public byte getReserved() {
        return reserved;
    }

    /**
     * Set the reserved field.
     *
     * @param reserved should be 0
     */
    public void setReserved(byte reserved) {
        this.reserved = reserved;
    }

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

    /**
     * Set the checksum.
     *
     * @param checksum the checksum
     */
    public void setChecksum(short checksum) {
        this.checksum = checksum;
    }

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

    /**
     * Serializes the packet. Will compute and set the following fields if they
     * are set to specific values at the time serialize is called: -checksum : 0
     * -length : 0
     *
     * @return will return the serialized packet
     */
    @Override
    public byte[] serialize() {
        int length = 4;
        byte[] payloadData = null;
        if (this.payload != null) {
            this.payload.setParent(this);
            payloadData = this.payload.serialize();
            length += payloadData.length;
        }

        final byte[] data = new byte[length];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.put((byte) ((this.version & 0xf) << 4 | this.type & 0xf));
        bb.put(this.reserved);
        bb.putShort(this.checksum);
        if (payloadData != null) {
            bb.put(payloadData);
        }

        if (this.parent != null && this.parent instanceof PIM) {
            ((PIM) this.parent).setPIMType(TYPE_JOIN_PRUNE_REQUEST);
        }

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

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

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

    /**
     * Deserialize the PIM packet.
     *
     * @param data bytes to deserialize.
     * @param offset offset to start deserializing from
     * @param length length of the data to deserialize
     *
     * @return the deserialized PIM packet.
     */
    @Override
    public IPacket deserialize(final byte[] data, final int offset,
            final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        this.type = bb.get();
        this.version = bb.get();
        this.checksum = bb.getShort();

        //this.payload = new Data();
        this.payload = this.payload.deserialize(data, bb.position(), bb.limit() - bb.position());
        this.payload.setParent(this);
        return this;
    }
    /**
     * Deserializer function for IPv4 packets.
     *
     * @return deserializer function
     */
    public static Deserializer<PIM> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, PIM_HEADER_LEN);

            PIM pim = new PIM();

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

            byte versionByte = bb.get();
            pim.version = (byte) (versionByte >> 4 & 0xf);
            pim.setPIMType((byte) (versionByte & 0xf));
            pim.reserved = bb.get();
            pim.checksum = bb.getShort();

            Deserializer<? extends IPacket> deserializer;
            if (PIM.PROTOCOL_DESERIALIZER_MAP.containsKey(pim.getPimMsgType())) {
                deserializer = PIM.PROTOCOL_DESERIALIZER_MAP.get(pim.getPimMsgType());
            } else {
                deserializer = Data.deserializer();
            }

            pim.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
            pim.payload.setParent(pim);

            return pim;
        };
    }
}
