/*
 * 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.onosproject.pcepio.types;

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

/**
 * Provides PCEP Object Header which is common for all the objects.
 * Reference : RFC 5440.
 */

public class PcepObjectHeader {

    /*
        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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       //                        (Object body)                        //
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                      PCEP Common Object Header
     */

    protected static final Logger log = LoggerFactory.getLogger(PcepObjectHeader.class);

    public static final boolean REQ_OBJ_MUST_PROCESS = true;
    public static final boolean REQ_OBJ_OPTIONAL_PROCESS = false;
    public static final boolean RSP_OBJ_IGNORED = true;
    public static final boolean RSP_OBJ_PROCESSED = false;
    public static final int OBJECT_TYPE_SHIFT_VALUE = 4;
    public static final byte PFLAG_SET = 0x02;
    public static final byte IFLAG_SET = 0x01;
    public static final int SET = 1;
    private byte objClass;
    private byte objType;
    private boolean bPFlag;
    private boolean bIFlag;
    private short objLen;

    /**
     * Constructor to initialize all the variables in object header.
     *
     * @param objClass PCEP Object class
     * @param objType PCEP Object type
     * @param bPFlag P flag
     * @param bIFlag I flag
     * @param objLen PCEP object length
     */

    public PcepObjectHeader(byte objClass, byte objType, boolean bPFlag, boolean bIFlag, short objLen) {
        this.objClass = objClass;
        this.objType = objType;
        this.bPFlag = bPFlag;
        this.bIFlag = bIFlag;
        this.objLen = objLen;
    }

    /**
     * Sets the Object class.
     *
     * @param value object class
     */
    public void setObjClass(byte value) {
        this.objClass = value;
    }

    /**
     * Sets the Object TYPE.
     *
     * @param value object type
     */
    public void setObjType(byte value) {
        this.objType = value;
    }

    /**
     * Sets the Object P flag.
     *
     * @param value p flag
     */
    public void setPFlag(boolean value) {
        this.bPFlag = value;
    }

    /**
     * Sets the Object I flag.
     *
     * @param value I flag
     */
    public void setIFlag(boolean value) {
        this.bIFlag = value;
    }

    /**
     * Sets the Object Length.
     *
     * @param value object length
     */
    public void setObjLen(short value) {
        this.objLen = value;
    }

    /**
     * Returns Object's P flag.
     *
     * @return bPFlag P flag
     */
    public boolean getPFlag() {
        return this.bPFlag;
    }

    /**
     * Returns Object's i flag.
     *
     * @return bIFlag I flag
     */
    public boolean getIFlag() {
        return this.bIFlag;
    }

    /**
     * Returns Object Length.
     *
     * @return objLen object length
     */
    public short getObjLen() {
        return this.objLen;
    }

    /**
     * Returns Object class.
     *
     * @return objClass object class
     */
    public byte getObjClass() {
        return this.objClass;
    }

    /**
     * Returns Object Type.
     *
     * @return objType object type
     */
    public byte getObjType() {
        return this.objType;
    }

    /**
     *  Writes Byte stream of PCEP object header to channel buffer.
     *
     * @param bb of type channel buffer
     * @return objLenIndex object length index in channel buffer
     */
    public int write(ChannelBuffer bb) {

        bb.writeByte(this.objClass);
        byte temp = (byte) (this.objType << OBJECT_TYPE_SHIFT_VALUE);
        if (this.bPFlag) {
            temp = (byte) (temp | PFLAG_SET);
        }
        if (this.bIFlag) {
            temp = (byte) (temp | IFLAG_SET);
        }
        bb.writeByte(temp);
        int objLenIndex = bb.writerIndex();
        bb.writeShort((short) 0);
        return objLenIndex;
    }

    /**
     * Read from channel buffer and Returns PCEP Objects header.
     *
     * @param bb of type channel buffer
     * @return PCEP Object header
     */
    public static PcepObjectHeader read(ChannelBuffer bb) {

        byte objClass;
        byte objType;
        boolean bPFlag;
        boolean bIFlag;
        short objLen;
        objClass = bb.readByte();
        byte temp = bb.readByte();
        bIFlag = ((temp & IFLAG_SET) == IFLAG_SET) ? true : false;
        bPFlag = ((temp & PFLAG_SET) == PFLAG_SET) ? true : false;
        objType = (byte) (temp >> OBJECT_TYPE_SHIFT_VALUE);
        objLen = bb.readShort();
        return new PcepObjectHeader(objClass, objType, bPFlag, bIFlag, objLen);
    }

    /**
     * Prints the Attributes of PCEP Object header.
     */
    public void print() {

        log.debug("PcepObjectHeader");
        log.debug("Object Class: " + objClass);
        log.debug("Object Type: " + objType);
        log.debug("Object Length: " + objLen);
        log.debug("P flag: " + bPFlag);
        log.debug("I flag: " + bIFlag);
    }
}
