/*
 * Copyright 2015-present 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.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.PcepLspObject;
import org.onosproject.pcepio.types.PcepErrorDetailInfo;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.onosproject.pcepio.types.PcepValueType;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
import org.onosproject.pcepio.types.StatefulLspDbVerTlv;
import org.onosproject.pcepio.types.StatefulLspErrorCodeTlv;
import org.onosproject.pcepio.types.StatefulRsvpErrorSpecTlv;
import org.onosproject.pcepio.types.SymbolicPathNameTlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP lsp object.
 */
public class PcepLspObjectVer1 implements PcepLspObject {

    /*
     message format.
     Reference : draft-ietf-pce-stateful-pce-11, section 7.3.
      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)       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                PLSP-ID                |  Flag |C|    O|A|R|S|D|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     //                        TLVs                                 //
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                     The LSP Object format
     */
    protected static final Logger log = LoggerFactory.getLogger(PcepLspObjectVer1.class);

    public static final byte LSP_OBJ_TYPE = 1;
    public static final byte LSP_OBJ_CLASS = 32;
    public static final byte LSP_OBJECT_VERSION = 1;

    // LSP_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ LspObjectHeaderLen(4)+TlvAssumedMinLength(8)
    public static final short LSP_OBJ_MINIMUM_LENGTH = 16;

    public static final int DEFAULT_PLSPID = 0;
    public static final byte DEFAULT_OFLAG = 1;
    public static final boolean DEFAULT_AFLAG = false;
    public static final boolean DEFAULT_RFLAG = false;
    public static final boolean DEFAULT_SFLAG = false;
    public static final boolean DEFAULT_DFLAG = false;
    public static final boolean DEFAULT_CFLAG = false;
    public static final int OBJECT_HEADER_LENGTH = 4;
    public static final int PLSPID_SHIFT_VALUE = 12;
    public static final int CFLAG_SHIFT_VALUE = 7;
    public static final int OFLAG_SHIFT_VALUE = 4;
    public static final int AFLAG_SHIFT_VALUE = 3;
    public static final int RFLAG_SHIFT_VALUE = 2;
    public static final int SFLAG_SHIFT_VALUE = 1;
    public static final int PLSPID_TEMP_SHIFT_VALUE = 0xFFFFF000;
    public static final int CFLAG_TEMP_SHIFT_VALUE = 0x80;
    public static final int OFLAG_TEMP_SHIFT_VALUE = 0x70;
    public static final int AFLAG_TEMP_SHIFT_VALUE = 0x08;
    public static final int RFLAG_TEMP_SHIFT_VALUE = 0x04;
    public static final int SFLAG_TEMP_SHIFT_VALUE = 0x02;
    public static final int DFLAG_TEMP_SHIFT_VALUE = 0x01;
    public static final int BIT_SET = 1;
    public static final int BIT_RESET = 0;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;

    static final PcepObjectHeader DEFAULT_LSP_OBJECT_HEADER = new PcepObjectHeader(LSP_OBJ_CLASS, LSP_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LSP_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader lspObjHeader;
    private int iPlspId;
    // 3-bits
    private byte yOFlag;
    private boolean bAFlag;
    private boolean bRFlag;
    private boolean bSFlag;
    private boolean bDFlag;
    private boolean bCFlag;

    // Optional TLV
    private LinkedList<PcepValueType> llOptionalTlv;

    /**
     * Constructor to initialize all the member variables.
     *
     * @param lspObjHeader lsp object header
     * @param iPlspId plsp id
     * @param yOFlag O flag
     * @param bAFlag A flag
     * @param bRFlag R flag
     * @param bSFlag S flag
     * @param bDFlag D flag
     * @param bCFlag C flag
     * @param llOptionalTlv list of optional tlv
     */
    public PcepLspObjectVer1(PcepObjectHeader lspObjHeader, int iPlspId, byte yOFlag, boolean bAFlag, boolean bRFlag,
            boolean bSFlag, boolean bDFlag, boolean bCFlag, LinkedList<PcepValueType> llOptionalTlv) {

        this.lspObjHeader = lspObjHeader;
        this.iPlspId = iPlspId;
        this.yOFlag = yOFlag;
        this.bAFlag = bAFlag;
        this.bRFlag = bRFlag;
        this.bSFlag = bSFlag;
        this.bDFlag = bDFlag;
        this.bCFlag = bCFlag;
        this.llOptionalTlv = llOptionalTlv;
    }

    /**
     * Sets lsp Object Header.
     *
     * @param obj lsp object header
     */
    public void setLspObjHeader(PcepObjectHeader obj) {
        this.lspObjHeader = obj;
    }

    @Override
    public void setPlspId(int iPlspId) {
        this.iPlspId = iPlspId;
    }

    @Override
    public void setCFlag(boolean bCFlag) {
        this.bCFlag = bCFlag;
    }

    @Override
    public void setOFlag(byte yOFlag) {
        this.yOFlag = yOFlag;
    }

    @Override
    public void setAFlag(boolean bAFlag) {
        this.bAFlag = bAFlag;
    }

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

    @Override
    public void setSFlag(boolean bSFlag) {
        this.bSFlag = bSFlag;
    }

    @Override
    public void setDFlag(boolean bDFlag) {
        this.bDFlag = bDFlag;
    }

    /**
     * Returns lsp object header.
     *
     * @return lspObjHeader
     */
    public PcepObjectHeader getLspObjHeader() {
        return this.lspObjHeader;
    }

    @Override
    public int getPlspId() {
        return this.iPlspId;
    }

    @Override
    public boolean getCFlag() {
        return this.bCFlag;
    }

    @Override
    public byte getOFlag() {
        return this.yOFlag;
    }

    @Override
    public boolean getAFlag() {
        return this.bAFlag;
    }

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

    @Override
    public boolean getSFlag() {
        return this.bSFlag;
    }

    @Override
    public boolean getDFlag() {
        return this.bDFlag;
    }

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

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

    /**
     * Parse channel buffer and returns object of PcepLspObject.
     *
     * @param cb of type channel buffer
     * @return object of  PcepLspObject
     * @throws PcepParseException when lsp object is not present in channel buffer
     */
    public static PcepLspObject read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader lspObjHeader;
        int iPlspId;
        // 3-bits
        byte yOFlag;
        boolean bAFlag;
        boolean bRFlag;
        boolean bSFlag;
        boolean bDFlag;
        boolean bCFlag;

        // Optional TLV
        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        lspObjHeader = PcepObjectHeader.read(cb);

        if (lspObjHeader.getObjClass() != PcepLspObjectVer1.LSP_OBJ_CLASS) {
            throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_6, PcepErrorDetailInfo.ERROR_VALUE_8);
        }
        //take only LspObject buffer.
        ChannelBuffer tempCb = cb.readBytes(lspObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);

        Integer iTemp = tempCb.readInt();
        iPlspId = (iTemp & PLSPID_TEMP_SHIFT_VALUE) >> PLSPID_SHIFT_VALUE;
        bCFlag = ((iTemp & CFLAG_TEMP_SHIFT_VALUE) >> CFLAG_SHIFT_VALUE) > 0;
        Integer iX = (iTemp & OFLAG_TEMP_SHIFT_VALUE) >> OFLAG_SHIFT_VALUE;
        yOFlag = iX.byteValue();
        iX = (iTemp & AFLAG_TEMP_SHIFT_VALUE) >> AFLAG_SHIFT_VALUE;
        bAFlag = iX > 0;
        iX = (iTemp & RFLAG_TEMP_SHIFT_VALUE) >> RFLAG_SHIFT_VALUE;
        bRFlag = iX > 0;
        iX = (iTemp & SFLAG_TEMP_SHIFT_VALUE) >> SFLAG_SHIFT_VALUE;
        bSFlag = iX > 0;
        iX = iTemp & DFLAG_TEMP_SHIFT_VALUE;
        bDFlag = iX > 0;

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

        return new PcepLspObjectVer1(lspObjHeader, iPlspId, yOFlag, bAFlag, bRFlag, bSFlag, bDFlag, bCFlag,
                                     llOptionalTlv);
    }

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

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

        int objLenIndex = lspObjHeader.write(cb);

        if (objLenIndex <= 0) {
            throw new PcepParseException("Failed to write lsp object header. Index " + objLenIndex);
        }

        int iTemp = iPlspId << PLSPID_SHIFT_VALUE;

        iTemp = iTemp | (((bCFlag) ? BIT_SET : BIT_RESET) << CFLAG_SHIFT_VALUE);

        iTemp = iTemp | (yOFlag << OFLAG_SHIFT_VALUE);
        byte bFlag;
        iTemp = bAFlag ? (iTemp | AFLAG_TEMP_SHIFT_VALUE) : iTemp;

        bFlag = (bRFlag) ? (byte) BIT_SET : BIT_RESET;
        iTemp = iTemp | (bFlag << RFLAG_SHIFT_VALUE);
        bFlag = (bSFlag) ? (byte) BIT_SET : BIT_RESET;
        iTemp = iTemp | (bFlag << SFLAG_SHIFT_VALUE);
        bFlag = (bDFlag) ? (byte) BIT_SET : BIT_RESET;
        iTemp = iTemp | bFlag;
        cb.writeInt(iTemp);

        // Add optional TLV
        packOptionalTlv(cb);

        //Update object length now
        int length = cb.writerIndex() - objStartIndex;
        //will be helpful during print().
        lspObjHeader.setObjLen((short) length);
        // As per RFC the length of object should be
        // multiples of 4

        cb.setShort(objLenIndex, (short) length);

        return length;
    }

    /**
     * Returns Linked list of optional tlvs.
     *
     * @param cb of channel buffer.
     * @return list of optional tlvs
     * @throws PcepParseException when unsupported tlv is received
     */
    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {

        LinkedList<PcepValueType> llOutOptionalTlv;

        llOutOptionalTlv = new LinkedList<>();

        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {

            PcepValueType tlv;
            short hType = cb.readShort();
            short hLength = cb.readShort();
            int iValue = 0;

            switch (hType) {

            case StatefulIPv4LspIdentifiersTlv.TYPE:
                tlv = StatefulIPv4LspIdentifiersTlv.read(cb);
                break;
            case StatefulLspErrorCodeTlv.TYPE:
                iValue = cb.readInt();
                tlv = new StatefulLspErrorCodeTlv(iValue);
                break;
            case StatefulRsvpErrorSpecTlv.TYPE:
                tlv = StatefulRsvpErrorSpecTlv.read(cb);
                break;
            case SymbolicPathNameTlv.TYPE:
                tlv = SymbolicPathNameTlv.read(cb, hLength);
                break;
            case StatefulLspDbVerTlv.TYPE:
                tlv = StatefulLspDbVerTlv.read(cb);
                break;
            default:
                throw new PcepParseException("Received unsupported TLV type :" + hType);
            }
            // Check for the padding
            int pad = hLength % 4;
            if (0 < pad) {
                pad = 4 - pad;
                if (pad <= cb.readableBytes()) {
                    cb.skipBytes(pad);
                }
            }

            llOutOptionalTlv.add(tlv);
        }

        if (0 < cb.readableBytes()) {

            throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
        }
        return llOutOptionalTlv;
    }

    /**
     * returns writer index.
     *
     * @param cb of type channel buffer
     * @return length of bytes written to channel buffer
     */
    protected int packOptionalTlv(ChannelBuffer cb) {

        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
        int startIndex = cb.writerIndex();

        while (listIterator.hasNext()) {
            PcepValueType tlv = listIterator.next();

            if (tlv == null) {
                log.debug("tlv is null from OptionalTlv list");
                continue;
            }

            tlv.write(cb);

            // need to take care of padding
            int pad = tlv.getLength() % 4;

            if (0 != pad) {
                pad = 4 - pad;
                for (int i = 0; i < pad; ++i) {
                    cb.writeByte((byte) 0);
                }
            }
        }

        return cb.writerIndex() - startIndex;
    }

    /**
     * Builder class for PCEP lsp Object.
     */
    public static class Builder implements PcepLspObject.Builder {

        private boolean bIsHeaderSet = false;
        private boolean bIsPlspIdSet = false;
        private boolean bIsOFlagSet = false;
        private boolean bIsRFlagSet = false;
        private boolean bIsAFlagSet = false;
        private boolean bIsDFlagSet = false;
        private boolean bIsSFlagSet = false;
        private boolean bIsCFlagSet = false;

        private PcepObjectHeader lspObjHeader;
        private byte yOFlag;
        private boolean bAFlag;
        private boolean bDFlag;
        private boolean bSFlag;
        private boolean bRFlag;
        private boolean bCFlag;
        LinkedList<PcepValueType> llOptionalTlv = null;

        private int plspId;

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepLspObject build() {
            PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.lspObjHeader : DEFAULT_LSP_OBJECT_HEADER;

            int plspId = this.bIsPlspIdSet ? this.plspId : DEFAULT_PLSPID;
            byte yOFlag = this.bIsOFlagSet ? this.yOFlag : DEFAULT_OFLAG;
            boolean bAFlag = this.bIsAFlagSet ? this.bAFlag : DEFAULT_AFLAG;
            boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;
            boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : DEFAULT_SFLAG;
            boolean bDFlag = this.bIsDFlagSet ? this.bDFlag : DEFAULT_DFLAG;
            boolean bCFlag = this.bIsCFlagSet ? this.bCFlag : DEFAULT_CFLAG;

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

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

            return new PcepLspObjectVer1(lspObjHeader, plspId, yOFlag, bAFlag, bRFlag, bSFlag, bDFlag, bCFlag,
                                         llOptionalTlv);
        }

        @Override
        public PcepObjectHeader getLspObjHeader() {
            return this.lspObjHeader;
        }

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

        @Override
        public int getPlspId() {
            return this.plspId;
        }

        @Override
        public Builder setPlspId(int value) {
            this.plspId = value;
            this.bIsPlspIdSet = true;
            return this;
        }

        @Override
        public boolean getCFlag() {
            return this.bCFlag;
        }

        @Override
        public Builder setCFlag(boolean value) {
            this.bCFlag = value;
            this.bIsCFlagSet = true;
            return this;
        }

        @Override
        public byte getOFlag() {
            return this.yOFlag;
        }

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

        @Override
        public boolean getAFlag() {
            return this.bAFlag;
        }

        @Override
        public Builder setAFlag(boolean value) {
            this.bAFlag = value;
            this.bIsAFlagSet = 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 boolean getSFlag() {
            return this.bSFlag;
        }

        @Override
        public Builder setSFlag(boolean value) {
            this.bSFlag = value;
            this.bIsSFlagSet = true;
            return this;
        }

        @Override
        public boolean getDFlag() {
            return this.bDFlag;
        }

        @Override
        public Builder setDFlag(boolean value) {
            this.bDFlag = value;
            this.bIsDFlagSet = 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 String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("PlspIDValue", iPlspId)
                .add("CFlag", bCFlag)
                .add("OFlag", yOFlag)
                .add("AFlag", bAFlag)
                .add("RFlag", bRFlag)
                .add("SFlag", bSFlag)
                .add("DFlag", bDFlag)
                .add("OptionalTlvList", llOptionalTlv)
                .toString();
    }
}
