/*
 * 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.PcepLabelObject;
import org.onosproject.pcepio.types.NexthopIPv4addressTlv;
import org.onosproject.pcepio.types.NexthopIPv6addressTlv;
import org.onosproject.pcepio.types.NexthopUnnumberedIPv4IDTlv;
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 object.
 */
public class PcepLabelObjectVer1 implements PcepLabelObject {

    /*
     *   ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.4.

        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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       | Reserved                      | Flags                       |O|
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                            Label                              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       //                        Optional TLV                          //
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     The LABEL Object format
     */
    protected static final Logger log = LoggerFactory.getLogger(PcepLspObjectVer1.class);

    public static final byte LABEL_OBJ_TYPE = 1;
    public static final byte LABEL_OBJ_CLASS = 35; //TBD : to be defined
    public static final byte LABEL_OBJECT_VERSION = 1;
    public static final byte OBJECT_HEADER_LENGTH = 4;
    public static final boolean DEFAULT_OFLAG = false;

    // LSP_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ LspObjectHeaderLen(8)
    public static final short LABEL_OBJ_MINIMUM_LENGTH = 12;

    public static final int OFLAG_SET = 1;
    public static final int OFLAG_RESET = 0;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;

    static final PcepObjectHeader DEFAULT_LABEL_OBJECT_HEADER = new PcepObjectHeader(LABEL_OBJ_CLASS, LABEL_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LABEL_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader labelObjHeader;
    private boolean bOFlag;
    private int label;
    // Optional TLV
    private LinkedList<PcepValueType> llOptionalTlv;

    /**
     * Constructor to initialize parameters for PCEP label object.
     *
     * @param labelObjHeader label object header
     * @param bOFlag O flag
     * @param label label
     * @param llOptionalTlv list of optional tlvs
     */
    public PcepLabelObjectVer1(PcepObjectHeader labelObjHeader, boolean bOFlag, int label,
            LinkedList<PcepValueType> llOptionalTlv) {
        this.labelObjHeader = labelObjHeader;
        this.bOFlag = bOFlag;
        this.label = label;
        this.llOptionalTlv = llOptionalTlv;
    }

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

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

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

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

    @Override
    public int getLabel() {
        return this.label;
    }

    @Override
    public void setLabel(int value) {
        this.label = value;
    }

    /**
     * Reads form channel buffer and returns objects of PcepLabelObject.
     *
     * @param cb of type channel buffer
     * @return objects of PcepLabelObject
     * @throws PcepParseException when fails to read from channel buffer
     */
    public static PcepLabelObject read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader labelObjHeader;

        boolean bOFlag;
        int label;

        // Optional TLV
        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
        labelObjHeader = PcepObjectHeader.read(cb);

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

        int iTemp = tempCb.readInt();
        bOFlag = (iTemp & (byte) 0x01) == 1;
        label = tempCb.readInt();

        // parse optional TLV
        llOptionalTlv = parseOptionalTlv(tempCb);
        return new PcepLabelObjectVer1(labelObjHeader, bOFlag, label, llOptionalTlv);
    }

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

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

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

        byte oFlag;

        oFlag = (byte) ((bOFlag) ? OFLAG_SET : OFLAG_RESET);
        cb.writeInt(oFlag);
        cb.writeInt(label);

        // Add optional TLV
        packOptionalTlv(cb);

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

        //will be helpful during print().
        labelObjHeader.setObjLen((short) length);
        cb.setShort(objLenIndex, (short) length);
        return cb.writerIndex();
    }

    /**
     * Returns list of optional tlvs.
     *
     * @param cb of type channel buffer
     * @return list of optional tlvs.
     * @throws PcepParseException when fails to parse list of optional tlvs
     */
    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {

        LinkedList<PcepValueType> 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 NexthopIPv4addressTlv.TYPE:
                iValue = cb.readInt();
                tlv = new NexthopIPv4addressTlv(iValue);
                break;
            case NexthopIPv6addressTlv.TYPE:
                byte[] ipv6Value = new byte[NexthopIPv6addressTlv.VALUE_LENGTH];
                cb.readBytes(ipv6Value, 0, NexthopIPv6addressTlv.VALUE_LENGTH);
                tlv = new NexthopIPv6addressTlv(ipv6Value);
                break;
            case NexthopUnnumberedIPv4IDTlv.TYPE:
                tlv = NexthopUnnumberedIPv4IDTlv.read(cb);
                break;
            default:
                throw new PcepParseException("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 the writer index.
     *
     * @param cb of channel buffer.
     * @return writer index
     */
    protected int packOptionalTlv(ChannelBuffer cb) {

        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();

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

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

    /**
     * Builder class for PCEP label object.
     */
    public static class Builder implements PcepLabelObject.Builder {

        private boolean bIsHeaderSet = false;
        private boolean bIsOFlagSet = false;
        private boolean bIsLabelSet = false;

        private PcepObjectHeader labelObjHeader;
        private boolean bOFlag;
        private int label;

        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepLabelObject build() throws PcepParseException {
            PcepObjectHeader labelObjHeader = this.bIsHeaderSet ? this.labelObjHeader : DEFAULT_LABEL_OBJECT_HEADER;
            boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;

            if (!this.bIsLabelSet) {
                throw new PcepParseException(" Label NOT Set while building PcepLabelObject.");
            }
            if (bIsPFlagSet) {
                labelObjHeader.setPFlag(bPFlag);
            }
            if (bIsIFlagSet) {
                labelObjHeader.setIFlag(bIFlag);
            }
            return new PcepLabelObjectVer1(labelObjHeader, bOFlag, this.label, this.llOptionalTlv);
        }

        @Override
        public PcepObjectHeader getLabelObjHeader() {
            return this.labelObjHeader;
        }

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

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

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

        @Override
        public int getLabel() {
            return this.label;
        }

        @Override
        public Builder setLabel(int value) {
            this.label = value;
            this.bIsLabelSet = true;
            return this;
        }

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

        @Override
        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
            this.llOptionalTlv = llOptionalTlv;
            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("OFlag", bOFlag)
                .add("label", label)
                .add("OptionalTlvList", llOptionalTlv)
                .toString();
    }
}
