/*
 * 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.ipv6;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.DeserializationException;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;

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

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

/**
 * Implements IPv6 routing extension header format. (RFC 2460)
 */
public class Routing extends BasePacket implements IExtensionHeader {
    public static final byte FIXED_HEADER_LENGTH = 4; // bytes
    public static final byte FIXED_ROUTING_DATA_LENGTH = 4; // bytes
    public static final byte LENGTH_UNIT = 8; // bytes per unit

    protected byte nextHeader;
    protected byte headerExtLength;
    protected byte routingType;
    protected byte segmentsLeft;
    protected byte[] routingData;

    @Override
    public byte getNextHeader() {
        return this.nextHeader;
    }

    @Override
    public Routing setNextHeader(final byte nextHeader) {
        this.nextHeader = nextHeader;
        return this;
    }

    /**
     * Gets the extension length of this header.
     *
     * @return header length
     */
    public byte getHeaderExtLength() {
        return this.headerExtLength;
    }

    /**
     * Sets the extension length of this header.
     *
     * @param headerExtLength the header length to set
     * @return this
     */
    public Routing setHeaderExtLength(final byte headerExtLength) {
        this.headerExtLength = headerExtLength;
        return this;
    }

    /**
     * Gets the routing type of this header.
     *
     * @return routing type
     */
    public byte getRoutingType() {
        return this.routingType;
    }

    /**
     * Sets the routing type of this header.
     *
     * @param routingType the routing type to set
     * @return this
     */
    public Routing setRoutingType(final byte routingType) {
        this.routingType = routingType;
        return this;
    }

    /**
     * Gets the number of remaining route segments of this header.
     *
     * @return number of remaining route segments
     */
    public byte getSegmentsLeft() {
        return this.segmentsLeft;
    }

    /**
     * Sets the number of remaining route segments of this header.
     *
     * @param segmentsLeft the number of remaining route segments to set
     * @return this
     */
    public Routing setSegmntsLeft(final byte segmentsLeft) {
        this.segmentsLeft = segmentsLeft;
        return this;
    }

    /**
     * Gets the routing data.
     *
     * @return the routing data
     */
    public byte[] getRoutingData() {
        return this.routingData;
    }

    /**
     * Sets the routing data.
     *
     * @param routingData the routing data to set
     * @return this
     */
    public Routing setRoutingData(final byte[] routingData) {
        this.routingData =
                Arrays.copyOfRange(routingData, 0, routingData.length);
        return this;
    }

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

        int headerLength = FIXED_HEADER_LENGTH + routingData.length;
        int payloadLength = 0;
        if (payloadData != null) {
            payloadLength = payloadData.length;
        }

        final byte[] data = new byte[headerLength + payloadLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.put(this.nextHeader);
        bb.put(this.headerExtLength);
        bb.put(this.routingType);
        bb.put(this.segmentsLeft);
        bb.put(this.routingData, 0, routingData.length);

        if (payloadData != null) {
            bb.put(payloadData);
        }

        if (this.parent != null && this.parent instanceof IExtensionHeader) {
            ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ROUTING);
        }
        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        this.nextHeader = bb.get();
        this.headerExtLength = bb.get();
        this.routingType = bb.get();
        this.segmentsLeft = bb.get();
        int dataLength =
                FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * this.headerExtLength;
        this.routingData = new byte[dataLength];
        bb.get(this.routingData, 0, dataLength);

        Deserializer<? extends IPacket> deserializer;
        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
        } else {
            deserializer = new 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.nextHeader;
        result = prime * result + this.headerExtLength;
        result = prime * result + this.routingType;
        result = prime * result + this.segmentsLeft;
        for (byte b : this.routingData) {
            result = prime * result + b;
        }
        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 Routing)) {
            return false;
        }
        final Routing other = (Routing) obj;
        if (this.nextHeader != other.nextHeader) {
            return false;
        }
        if (this.headerExtLength != other.headerExtLength) {
            return false;
        }
        if (this.routingType != other.routingType) {
            return false;
        }
        if (this.segmentsLeft != other.segmentsLeft) {
            return false;
        }
        if (!Arrays.equals(this.routingData, other.routingData)) {
            return false;
        }
        return true;
    }

    /**
     * Deserializer function for routing headers.
     *
     * @return deserializer function
     */
    public static Deserializer<Routing> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, FIXED_HEADER_LENGTH);

            Routing routing = new Routing();

            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            routing.nextHeader = bb.get();
            routing.headerExtLength = bb.get();
            routing.routingType = bb.get();
            routing.segmentsLeft = bb.get();
            int dataLength =
                    FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * routing.headerExtLength;

            checkHeaderLength(bb.remaining(), dataLength);

            routing.routingData = new byte[dataLength];
            bb.get(routing.routingData, 0, dataLength);

            Deserializer<? extends IPacket> deserializer;
            if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(routing.nextHeader)) {
                deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(routing.nextHeader);
            } else {
                deserializer = new Data().deserializer();
            }
            routing.payload = deserializer.deserialize(data, bb.position(),
                                               bb.limit() - bb.position());
            routing.payload.setParent(routing);

            return routing;
        };
    }
}
