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

import com.google.common.base.MoreObjects;

/**
 * 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 cb output channel buffer
     * @return objLenIndex object length index in channel buffer
     */
    public int write(ChannelBuffer cb) {

        cb.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);
        }
        cb.writeByte(temp);
        int objLenIndex = cb.writerIndex();
        cb.writeShort((short) 0);
        return objLenIndex;
    }

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

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

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("ObjectClass", objClass)
                .add("ObjectType", objType)
                .add("ObjectLength", objLen)
                .add("PFlag", (bPFlag) ? 1 : 0)
                .add("IFlag", (bIFlag) ? 1 : 0)
                .toString();
    }
}
