/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.bgpio.types;

import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides BGP Message Header which is common for all the Messages.
 */

public class BgpHeader {

    /*      0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          +                                                               +
          |                                                               |
          +                                                               +
          |                           Marker                              |
          +                                                               +
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |          Length               |      Type     |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    */

    private static final Logger log = LoggerFactory.getLogger(BgpHeader.class);

    public static final int MARKER_LENGTH = 16;
    public static final short DEFAULT_HEADER_LENGTH = 19;

    private byte[] marker;
    private byte type;
    private short length;

    /**
     * Reset fields.
     */
    public BgpHeader() {
        this.marker = null;
        this.length = 0;
        this.type = 0;
    }

    /**
     * Constructors to initialize parameters.
     *
     * @param marker field in BGP header
     * @param length message length
     * @param type message type
     */
    public BgpHeader(byte[] marker, short length, byte type) {
        this.marker = marker;
        this.length = length;
        this.type = type;
    }

    /**
     * Sets marker field.
     *
     * @param value marker field
     */
    public void setMarker(byte[] value) {
        this.marker = value;
    }

    /**
     * Sets message type.
     *
     * @param value message type
     */
    public void setType(byte value) {
        this.type = value;
    }

    /**
     * Sets message length.
     *
     * @param value message length
     */
    public void setLength(short value) {
        this.length = value;
    }

    /**
     * Returns message length.
     *
     * @return message length
     */
    public short getLength() {
        return this.length;
    }

    /**
     * Returns message marker.
     *
     * @return message marker
     */
    public byte[] getMarker() {
        return this.marker;
    }

    /**
     * Returns message type.
     *
     * @return message type
     */
    public byte getType() {
        return this.type;
    }

    /**
     * Writes Byte stream of BGP header to channel buffer.
     *
     * @param cb ChannelBuffer
     * @return length index of message header
     */
    public int write(ChannelBuffer cb) {

        cb.writeBytes(getMarker(), 0, MARKER_LENGTH);

        int headerLenIndex = cb.writerIndex();
        cb.writeShort((short) 0);
        cb.writeByte(type);

        return headerLenIndex;
    }

    /**
     * Read from channel buffer and Returns BGP header.
     *
     * @param cb ChannelBuffer
     * @return object of BGPHeader
     */
    public static BgpHeader read(ChannelBuffer cb) {

        byte[] marker = new byte[MARKER_LENGTH];
        byte type;
        short length;
        cb.readBytes(marker, 0, MARKER_LENGTH);
        length = cb.readShort();
        type = cb.readByte();
        return new BgpHeader(marker, length, type);
    }
}