/*
 * Copyright 2016 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.onosproject.routing.fpm.protocol;

import com.google.common.base.MoreObjects;
import org.onlab.packet.DeserializationException;

import java.nio.ByteBuffer;

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

/**
 * Netlink header.
 * <p>
 * Taken from struct nlmsghdr in linux/netlink.h
 * </p>
 */
public final class Netlink {

    public static final int NETLINK_HEADER_LENGTH = 16;

    private final long length;
    private final NetlinkMessageType type;
    private final int flags;
    private final long sequence;
    private final long processPortId;

    private final RtNetlink rtNetlink;

    /**
     * Class constructor.
     *
     * @param length message length
     * @param type type
     * @param flags flags
     * @param sequence sequence number
     * @param processPortId port ID
     * @param rtNetlink netlink routing message
     */
    private Netlink(long length, NetlinkMessageType type, int flags, long sequence,
                    long processPortId, RtNetlink rtNetlink) {
        this.length = length;
        this.type = type;
        this.flags = flags;
        this.sequence = sequence;
        this.processPortId = processPortId;
        this.rtNetlink = rtNetlink;
    }

    /**
     * Returns the message length.
     *
     * @return length
     */
    public long length() {
        return length;
    }

    /**
     * Returns the message type.
     *
     * @return message type
     */
    public NetlinkMessageType type() {
        return type;
    }

    /**
     * Returns the flags.
     *
     * @return flags
     */
    public int flags() {
        return flags;
    }

    /**
     * Returns the sequence number.
     *
     * @return sequence number
     */
    public long sequence() {
        return sequence;
    }

    /**
     * Returns the port ID.
     *
     * @return port ID
     */
    public long processPortId() {
        return processPortId;
    }

    /**
     * Returns the netlink routing message.
     *
     * @return netlink routing message
     */
    public RtNetlink rtNetlink() {
        return rtNetlink;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("length", length)
                .add("type", type)
                .add("flags", flags)
                .add("sequence", sequence)
                .add("processPortId", processPortId)
                .add("rtNetlink", rtNetlink)
                .toString();
    }

    /**
     * Decodes a netlink header from an input buffer.
     *
     * @param buffer input buffer
     * @param start starting position the netlink header
     * @param length length of the message
     * @return netlink header
     * @throws DeserializationException if a netlink header could not be
     * decoded from the input buffer
     */
    public static Netlink decode(byte[] buffer, int start, int length) throws
            DeserializationException {
        checkInput(buffer, start, length, NETLINK_HEADER_LENGTH);

        ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);

        long messageLength = Integer.reverseBytes(bb.getInt());
        int type = Short.reverseBytes(bb.getShort());
        int flags = Short.reverseBytes(bb.getShort());
        long sequence = Integer.reverseBytes(bb.getInt());
        long processPortId = Integer.reverseBytes(bb.getInt());

        NetlinkMessageType messageType = NetlinkMessageType.get(type);
        if (messageType == null) {
            throw new DeserializationException(
                    "Unsupported Netlink message type: " + type);
        }

        // Netlink messages from Quagga's FPM protocol are always in the
        // netlink route family (family 0).
        RtNetlink rtNetlink = RtNetlink.decode(buffer, bb.position(),
                bb.limit() - bb.position());

        return new Netlink(messageLength,
                messageType,
                flags,
                sequence,
                processPortId,
                rtNetlink);
    }

}
