/*
 * 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.pcepio.protocol.ver1;

import java.util.LinkedList;
import java.util.ListIterator;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepRPObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.onosproject.pcepio.types.PcepValueType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP RP object.
 */
public class PcepRPObjectVer1 implements PcepRPObject {

    /*
     *  RP Object.
    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
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          Flags                    |O|B|R| Pri |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                        Request-ID-number                      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    //                      Optional TLVs                          //
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     */

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

    public static final byte RP_OBJ_TYPE = 1;
    public static final byte RP_OBJ_CLASS = 2;
    public static final byte RP_OBJECT_VERSION = 1;
    public static final short RP_OBJ_MINIMUM_LENGTH = 12;

    public static final int DEFAULT_REQUEST_ID_NUM = 0;
    //Signalled , all default values to be checked.
    public static final boolean DEFAULT_OFLAG = false;
    public static final boolean DEFAULT_BFLAG = false;
    public static final boolean DEFAULT_RFLAG = false;
    public static final byte DEFAULT_PRIFLAG = 0;
    public static final int OBJECT_HEADER_LENGTH = 4;
    public static final int OFLAG_SHIFT_VALUE = 5;
    public static final int BFLAG_SHIFT_VALUE = 4;
    public static final int RFLAG_SHIFT_VALUE = 3;
    public static final int OFLAG_TEMP_SHIFT_VALUE = 0x20;
    public static final int BFLAG_TEMP_SHIFT_VALUE = 0x10;
    public static final int RFLAG_TEMP_SHIFT_VALUE = 0x08;
    public static final int PRIFLAG_TEMP_SHIFT_VALUE = 0x07;
    public static final int BIT_SET = 1;
    public static final int BIT_RESET = 0;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;

    public static final PcepObjectHeader DEFAULT_RP_OBJECT_HEADER = new PcepObjectHeader(RP_OBJ_CLASS, RP_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RP_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader rpObjHeader;
    private int iRequestIdNum;
    private boolean bOFlag;
    private boolean bBFlag;
    private boolean bRFlag;
    private byte yPriFlag; // 3bytes
    private LinkedList<PcepValueType> llOptionalTlv;

    /**
     * Constructor to initialize variables.
     *
     * @param rpObjHeader RP-OBJECT header
     * @param iRequestIdNum Request-ID-number
     * @param bOFlag O-flag
     * @param bBFlag B-flag
     * @param bRFlag R-flag
     * @param yPriFlag Pri-flag
     * @param llOptionalTlv linked list of Optional TLV
     */
    public PcepRPObjectVer1(PcepObjectHeader rpObjHeader, int iRequestIdNum, boolean bOFlag, boolean bBFlag,
            boolean bRFlag, byte yPriFlag, LinkedList<PcepValueType> llOptionalTlv) {
        this.rpObjHeader = rpObjHeader;
        this.iRequestIdNum = iRequestIdNum;
        this.bOFlag = bOFlag;
        this.bBFlag = bBFlag;
        this.bRFlag = bRFlag;
        this.yPriFlag = yPriFlag;
        this.llOptionalTlv = llOptionalTlv;
    }

    /**
     * Sets RP Object header.
     *
     * @param obj RP Object header
     */
    public void setRPObjHeader(PcepObjectHeader obj) {
        this.rpObjHeader = obj;
    }

    @Override
    public void setRequestIdNum(int iRequestIdNum) {
        this.iRequestIdNum = iRequestIdNum;
    }

    @Override
    public void setOFlag(boolean bOFlag) {
        this.bOFlag = bOFlag;
    }

    @Override
    public void setBFlag(boolean bBFlag) {
        this.bBFlag = bBFlag;
    }

    @Override
    public void setRFlag(boolean bRFlag) {
        this.bRFlag = bRFlag;
    }

    @Override
    public void setPriFlag(byte yPriFlag) {
        this.yPriFlag = yPriFlag;
    }

    /**
     * Returns RP Object header.
     *
     * @return rpObjHeader
     */
    public PcepObjectHeader getRPObjHeader() {
        return this.rpObjHeader;
    }

    @Override
    public int getRequestIdNum() {
        return this.iRequestIdNum;
    }

    @Override
    public boolean getOFlag() {
        return this.bOFlag;
    }

    @Override
    public boolean getBFlag() {
        return this.bBFlag;
    }

    @Override
    public boolean getRFlag() {
        return this.bRFlag;
    }

    @Override
    public byte getPriFlag() {
        return this.yPriFlag;
    }

    /**
     * Reads the channel buffer and returns the object of PcepRPObject.
     *
     * @param cb of type channel buffer
     * @return the object of PcepRPObject
     * @throws PcepParseException if mandatory fields are missing
     */
    public static PcepRPObject read(ChannelBuffer cb) throws PcepParseException {
        log.debug("read");
        PcepObjectHeader rpObjHeader;
        int iRequestIdNum;
        boolean bOFlag;
        boolean bBFlag;
        boolean bRFlag;
        byte yPriFlag; // 3bytes
        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        rpObjHeader = PcepObjectHeader.read(cb);

        //take only LspObject buffer.
        ChannelBuffer tempCb = cb.readBytes(rpObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);

        int iTemp = tempCb.readInt();
        yPriFlag = (byte) (iTemp & PRIFLAG_TEMP_SHIFT_VALUE);
        bOFlag = (iTemp & OFLAG_TEMP_SHIFT_VALUE) == OFLAG_TEMP_SHIFT_VALUE;
        bBFlag = (iTemp & BFLAG_TEMP_SHIFT_VALUE) == BFLAG_TEMP_SHIFT_VALUE;
        bRFlag = (iTemp & RFLAG_TEMP_SHIFT_VALUE) == RFLAG_TEMP_SHIFT_VALUE;

        iRequestIdNum = tempCb.readInt();

        // parse optional TLV
        llOptionalTlv = parseOptionalTlv(tempCb);

        return new PcepRPObjectVer1(rpObjHeader, iRequestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
    }

    @Override
    public int write(ChannelBuffer cb) throws PcepParseException {

        //write Object header
        int objStartIndex = cb.writerIndex();

        int objLenIndex = rpObjHeader.write(cb);

        if (objLenIndex <= 0) {
            throw new PcepParseException("ObjectLength Index is " + objLenIndex);
        }
        int iTemp;
        iTemp = (yPriFlag);

        iTemp = (bOFlag) ? (iTemp | OFLAG_SHIFT_VALUE) : iTemp;
        iTemp = (bBFlag) ? (iTemp | BFLAG_SHIFT_VALUE) : iTemp;
        iTemp = (bRFlag) ? (iTemp | RFLAG_SHIFT_VALUE) : iTemp;

        cb.writeInt(iTemp);
        cb.writeInt(iRequestIdNum);

        // Add optional TLV
        packOptionalTlv(cb);

        //Update object length now
        int length = cb.writerIndex() - objStartIndex;

        //will be helpful during print().
        rpObjHeader.setObjLen((short) length);

        cb.setShort(objLenIndex, (short) length);
        return cb.writerIndex();
    }

    /**
     * Returns list of optional tlvs.
     *
     * @param cb of type channel buffer.
     * @return llOutOptionalTlv linked list of Optional TLV
     * @throws PcepParseException if mandatory fields are missing
     */
    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {

        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
        //Currently no optional TLvs, will be added based on requirements.
        return llOutOptionalTlv;
    }

    /**
     * Returns optional tlvs.
     *
     * @param cb of type channel buffer
     * @return llOptionalTlv linked list of Optional TLV
     */
    protected int packOptionalTlv(ChannelBuffer cb) {

        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
        while (listIterator.hasNext()) {
            listIterator.next().write(cb);
        }

        return cb.writerIndex();
    }

    /**
     * Builder class for PCEP rp object.
     */
    public static class Builder implements PcepRPObject.Builder {

        private boolean bIsHeaderSet = false;
        private boolean bIsRequestIdNumSet = false;
        private boolean bIsOFlagSet = false;
        private boolean bIsRFlagset = false;
        private boolean bIsBFlagSet = false;
        private boolean bIsPriFlagSet = false;

        private PcepObjectHeader rpObjHeader;
        private int requestIdNum;
        private boolean bOFlag;
        private boolean bBFlag;
        private boolean bRFlag;
        private byte yPriFlag;
        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepRPObject build() {
            PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.rpObjHeader : DEFAULT_RP_OBJECT_HEADER;

            int requestIdNum = this.bIsRequestIdNumSet ? this.requestIdNum : DEFAULT_REQUEST_ID_NUM;
            boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;
            boolean bBFlag = this.bIsBFlagSet ? this.bBFlag : DEFAULT_BFLAG;
            boolean bRFlag = this.bIsRFlagset ? this.bRFlag : DEFAULT_RFLAG;
            byte yPriFlag = this.bIsPriFlagSet ? this.yPriFlag : DEFAULT_PRIFLAG;

            if (bIsPFlagSet) {
                lspObjHeader.setPFlag(bPFlag);
            }

            if (bIsIFlagSet) {
                lspObjHeader.setIFlag(bIFlag);
            }

            return new PcepRPObjectVer1(lspObjHeader, requestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
        }

        @Override
        public PcepObjectHeader getRPObjHeader() {
            return this.rpObjHeader;
        }

        @Override
        public Builder setRPObjHeader(PcepObjectHeader obj) {
            this.rpObjHeader = obj;
            this.bIsHeaderSet = true;
            return this;
        }

        @Override
        public int getRequestIdNum() {
            return this.requestIdNum;
        }

        @Override
        public Builder setRequestIdNum(int value) {
            this.requestIdNum = value;
            this.bIsRequestIdNumSet = true;
            return this;
        }

        @Override
        public Builder setOFlag(boolean value) {
            this.bOFlag = value;
            this.bIsOFlagSet = true;
            return this;
        }

        @Override
        public boolean getBFlag() {
            return this.bBFlag;
        }

        @Override
        public Builder setBFlag(boolean value) {
            this.bBFlag = value;
            this.bIsBFlagSet = true;
            return this;
        }

        @Override
        public boolean getRFlag() {
            return this.bRFlag;
        }

        @Override
        public Builder setRFlag(boolean value) {
            this.bRFlag = value;
            this.bIsRFlagset = true;
            return this;
        }

        @Override
        public byte getPriFlag() {
            return this.yPriFlag;
        }

        @Override
        public Builder setPriFlag(byte value) {
            this.yPriFlag = value;
            this.bIsPriFlagSet = true;
            return this;
        }

        @Override
        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
            this.llOptionalTlv = llOptionalTlv;
            return this;
        }

        @Override
        public LinkedList<PcepValueType> getOptionalTlv() {
            return this.llOptionalTlv;
        }

        @Override
        public Builder setPFlag(boolean value) {
            this.bPFlag = value;
            this.bIsPFlagSet = true;
            return this;
        }

        @Override
        public Builder setIFlag(boolean value) {
            this.bIFlag = value;
            this.bIsIFlagSet = true;
            return this;
        }

        @Override
        public boolean getOFlag() {
            return this.bOFlag;
        }

    }

    @Override
    public LinkedList<PcepValueType> getOptionalTlv() {
        return this.llOptionalTlv;
    }

    @Override
    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
        this.llOptionalTlv = llOptionalTlv;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("ObjectHeader", rpObjHeader)
                .add("OFlag", (bOFlag) ? 1 : 0)
                .add("BFlag", (bBFlag) ? 1 : 0)
                .add("RFlag", (bRFlag) ? 1 : 0)
                .add("PriFlag", yPriFlag)
                .add("RequestIdNumber", iRequestIdNum)
                .add("OptionalTlv", llOptionalTlv)
                .toString();
    }
}
