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

/**
 * Provides PCEP label range object.
 */
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();
    }
}
