/*
 * 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 = null;
            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:
                // Skip the unknown TLV.
                cb.skipBytes(hLength);
                tlv = null;
                log.info("Received unsupported TLV type :" + hType + " in LSP object.");
            }
            // Check for the padding
            int pad = hLength % 4;
            if (0 < pad) {
                pad = 4 - pad;
                if (pad <= cb.readableBytes()) {
                    cb.skipBytes(pad);
                }
            }

            if (tlv != null) {
                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();
    }
}
