/*
 * 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.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.PcepLabelRangeObject;
import org.onosproject.pcepio.types.PathSetupTypeTlv;
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;

public class PcepLabelRangeObjectVer1 implements PcepLabelRangeObject {

    /*
     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01, section : 7.2
            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
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | label type    | range size                                    |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                        label base                             |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                                                               |
           //                      Optional TLVs                           //
           |                                                               |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                               LABEL-RANGE Object
     */
    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeObjectVer1.class);

    public static final byte LABEL_RANGE_OBJ_TYPE = 1;
    public static final byte LABEL_RANGE_OBJ_CLASS = 60; //to be defined
    public static final byte LABEL_RANGE_OBJECT_VERSION = 1;
    public static final short LABEL_RANGE_OBJ_MINIMUM_LENGTH = 12;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
    //P flag and I flag must be set to 0
    static final PcepObjectHeader DEFAULT_LABELRANGE_OBJECT_HEADER = new PcepObjectHeader(LABEL_RANGE_OBJ_CLASS,
            LABEL_RANGE_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
            LABEL_RANGE_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader labelRangeObjHeader;
    private byte labelType;
    private int rangeSize;
    private int labelBase;
    //Optional TLV
    private LinkedList<PcepValueType> llOptionalTlv;

    /**
     * Constructor to initialize parameters for PCEP label range object.
     *
     * @param labelRangeObjHeader label range object header
     * @param labelType label type
     * @param rangeSize range size
     * @param labelBase label base
     * @param llOptionalTlv list of optional tlvs
     */
    public PcepLabelRangeObjectVer1(PcepObjectHeader labelRangeObjHeader, byte labelType, int rangeSize, int labelBase,
            LinkedList<PcepValueType> llOptionalTlv) {
        this.labelRangeObjHeader = labelRangeObjHeader;
        this.labelType = labelType;
        this.rangeSize = rangeSize;
        this.llOptionalTlv = llOptionalTlv;
        this.labelBase = labelBase;
    }

    @Override
    public void setLabelRangeObjHeader(PcepObjectHeader obj) {
        this.labelRangeObjHeader = obj;
    }

    @Override
    public void setLabelType(byte labelType) {
        this.labelType = labelType;
    }

    @Override
    public void setRangeSize(int rangeSize) {
        this.rangeSize = rangeSize;
    }

    @Override
    public void setLabelBase(int labelBase) {
        this.labelBase = labelBase;
    }

    @Override
    public PcepObjectHeader getLabelRangeObjHeader() {
        return this.labelRangeObjHeader;
    }

    @Override
    public byte getLabelType() {
        return this.labelType;
    }

    @Override
    public int getRangeSize() {
        return this.rangeSize;
    }

    @Override
    public int getLabelBase() {
        return this.labelBase;
    }

    /**
     * Reads from the channel buffer and returns object of  PcepLabelRangeObject.
     *
     * @param cb of type channel buffer
     * @return object of  PcepLabelRangeObject
     * @throws PcepParseException when fails to read from channel buffer
     */
    public static PcepLabelRangeObject read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader labelRangeObjHeader;
        byte labelType;
        int rangeSize;
        int labelBase;

        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();

        labelRangeObjHeader = PcepObjectHeader.read(cb);

        //take only LabelRangeObject buffer.
        ChannelBuffer tempCb = cb.readBytes(labelRangeObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
        int temp = 0;
        temp = tempCb.readInt();
        rangeSize = temp & 0x00FFFFFF;
        labelType = (byte) (temp >> 24);
        labelBase = tempCb.readInt();
        llOptionalTlv = parseOptionalTlv(tempCb);
        return new PcepLabelRangeObjectVer1(labelRangeObjHeader, labelType, rangeSize, labelBase, llOptionalTlv);
    }

    @Override
    public int write(ChannelBuffer cb) throws PcepParseException {

        int objStartIndex = cb.writerIndex();

        //write common header
        int objLenIndex = labelRangeObjHeader.write(cb);
        int temp = 0;
        temp = labelType;
        temp = temp << 24;
        temp = temp | rangeSize;
        cb.writeInt(temp);

        // Add optional TLV
        if (!packOptionalTlv(cb)) {
            throw new PcepParseException("Error while writing Optional tlv.");
        }

        //now write LabelRange Object Length
        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
        return cb.writerIndex() - objStartIndex;
    }

    /**
     * Returns list of optional tlvs.
     *
     * @param cb of type channle buffer
     * @return list of optional tlvs
     * @throws PcepParseException whne fails to parse list of optional tlvs
     */
    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {

        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();

        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {

            PcepValueType tlv;
            int iValue;
            short hType = cb.readShort();
            short hLength = cb.readShort();

            switch (hType) {

            case PathSetupTypeTlv.TYPE:
                iValue = cb.readInt();
                tlv = new PathSetupTypeTlv(iValue);
                break;

            default:
                throw new PcepParseException("Unsupported TLV in LabelRange Object.");
            }

            // Check for the padding
            int pad = hLength % 4;
            if (0 < pad) {
                pad = 4 - pad;
                if (pad <= cb.readableBytes()) {
                    cb.skipBytes(pad);
                }
            }
            llOutOptionalTlv.add(tlv);
        }
        return llOutOptionalTlv;
    }

    /**
     * Pack optional tlvs.
     *
     * @param cb of channel buffer
     * @return true
     */
    protected boolean packOptionalTlv(ChannelBuffer cb) {

        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();

        while (listIterator.hasNext()) {
            PcepValueType tlv = listIterator.next();

            if (null == tlv) {
                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 true;
    }

    /**
     * Builder class for PCEP label range object.
     */
    public static class Builder implements PcepLabelRangeObject.Builder {
        private boolean bIsHeaderSet = false;
        private boolean bIsLabelType = false;
        private boolean bIsRangeSize = false;
        private boolean bIsLabelBase = false;

        byte labelType;
        int rangeSize;
        int labelBase;
        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;
        private PcepObjectHeader labelRangeObjHeader;

        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();

        @Override
        public PcepLabelRangeObject build() throws PcepParseException {
            PcepObjectHeader labelRangeObjHeader = this.bIsHeaderSet ? this.labelRangeObjHeader
                    : DEFAULT_LABELRANGE_OBJECT_HEADER;

            if (!this.bIsLabelType) {
                throw new PcepParseException("LabelType NOT Set while building label range object.");
            }

            if (!this.bIsRangeSize) {
                throw new PcepParseException("RangeSize NOT Set while building label range object.");
            }

            if (!this.bIsLabelBase) {
                throw new PcepParseException("LabelBase NOT Set while building label range object.");
            }

            if (bIsPFlagSet) {
                labelRangeObjHeader.setPFlag(bPFlag);
            }

            if (bIsIFlagSet) {
                labelRangeObjHeader.setIFlag(bIFlag);
            }
            return new PcepLabelRangeObjectVer1(labelRangeObjHeader, this.labelType, this.rangeSize, this.labelBase,
                    this.llOptionalTlv);
        }

        @Override
        public PcepObjectHeader getLabelRangeObjHeader() {
            return this.labelRangeObjHeader;
        }

        @Override
        public Builder setLabelRangeObjHeader(PcepObjectHeader obj) {
            this.labelRangeObjHeader = obj;
            this.bIsHeaderSet = true;
            return this;
        }

        @Override
        public byte getLabelType() {
            return this.labelType;
        }

        @Override
        public Builder setLabelType(byte labelType) {
            this.labelType = labelType;
            this.bIsLabelType = true;
            return this;
        }

        @Override
        public int getRangeSize() {
            return this.rangeSize;
        }

        @Override
        public Builder setRangeSize(int rangeSize) {
            this.rangeSize = rangeSize;
            this.bIsRangeSize = true;
            return this;
        }

        @Override
        public int getLabelBase() {
            return this.labelBase;
        }

        @Override
        public Builder setLabelBase(int labelBase) {
            this.labelBase = labelBase;
            this.bIsLabelBase = true;
            return this;
        }

        @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("LabelType", labelType).add("rangeSize", rangeSize)
                .add("labelBase", labelBase).add("optionalTlvList", llOptionalTlv).toString();
    }
}
