/*
 * 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.PcepSrpObject;
import org.onosproject.pcepio.types.PathSetupTypeTlv;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.onosproject.pcepio.types.PcepValueType;
import org.onosproject.pcepio.types.SymbolicPathNameTlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP SRP obejct.
 */
public class PcepSrpObjectVer1 implements PcepSrpObject {

    /*
     * ref : draft-ietf-pce-stateful-pce-10, 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
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          Flags                              |R|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                        SRP-ID-number                          |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    //                      Optional TLVs                          //
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

     */
    protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);

    public static final byte SRP_OBJ_TYPE = 1;
    public static final byte SRP_OBJ_CLASS = 33;
    public static final byte SRP_OBJECT_VERSION = 1;
    public static final short SRP_OBJ_MINIMUM_LENGTH = 12;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
    public static final boolean DEFAULT_RFLAG = false;

    static final PcepObjectHeader DEFAULT_SRP_OBJECT_HEADER = new PcepObjectHeader(SRP_OBJ_CLASS, SRP_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, SRP_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader srpObjHeader;
    private static int flags;
    private boolean bRFlag;
    private int srpId;

    //Optional TLV
    private LinkedList<PcepValueType> llOptionalTlv;
    public static final byte BBIT_SET = 1;
    public static final byte BBIT_RESET = 0;

    /**
     * Constructor to initialize member variables.
     *
     * @param srpObjHeader srp object header
     * @param bRFlag R flag
     * @param srpID srp Id
     * @param llOptionalTlv list of optional tlv
     */
    public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, int srpID,
            LinkedList<PcepValueType> llOptionalTlv) {

        this.srpObjHeader = srpObjHeader;
        this.bRFlag = bRFlag;
        this.srpId = srpID;
        this.llOptionalTlv = llOptionalTlv;
    }

    /**
     * sets the SRP object header.
     *
     * @param obj srp object header
     */
    public void setSrpObjHeader(PcepObjectHeader obj) {
        this.srpObjHeader = obj;
    }

    @Override
    public void setSrpID(int srpID) {
        this.srpId = srpID;
    }

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

    /**
     * Returns SRP object header.
     *
     * @return srpObjHeader
     */
    public PcepObjectHeader getSrpObjHeader() {
        return this.srpObjHeader;
    }

    @Override
    public int getSrpID() {
        return this.srpId;
    }

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

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

    }

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

    /**
     * Reads from channel buffer and returns instance of PCEP SRP object.
     *
     * @param cb of channel buffer.
     * @return PCEP SRP object
     * @throws PcepParseException when srp object is not received in channel buffer
     */
    public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {

        log.debug("SrpObject::read");
        PcepObjectHeader srpObjHeader;
        boolean bRFlag;

        int srpID;
        int flags;
        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        srpObjHeader = PcepObjectHeader.read(cb);

        if (srpObjHeader.getObjClass() != SRP_OBJ_CLASS) {
            throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
        }

        //take only SrpObject buffer.
        ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
        flags = tempCb.readInt();
        bRFlag = 0 < flags;
        srpID = tempCb.readInt();

        llOptionalTlv = parseOptionalTlv(tempCb);

        return new PcepSrpObjectVer1(srpObjHeader, bRFlag, srpID, llOptionalTlv);
    }

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

        int objStartIndex = cb.writerIndex();

        //write common header
        int objLenIndex = srpObjHeader.write(cb);

        //write Flags
        byte bFlag;

        bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;

        cb.writeInt(bFlag);

        //write SrpId
        cb.writeInt(srpId);

        // Add optional TLV
        if (!packOptionalTlv(cb)) {
            throw new PcepParseException("Failed to write srp tlv to channel buffer.");
        }

        //now write SRP Object Length
        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));

        return cb.writerIndex();
    }

    /**
     * Parse Optional TLvs from the channel buffer.
     *
     * @param cb of type channel buffer
     * @return list of optional tlvs
     * @throws PcepParseException when unsupported tlv is received in srp object
     */
    public 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();

            switch (hType) {
            case SymbolicPathNameTlv.TYPE:
                if (cb.readableBytes() < hLength) {
                    throw new PcepParseException("Length is not valid in SymbolicPathNameTlv");
                }
                tlv = SymbolicPathNameTlv.read(cb, hLength);
                break;
            case PathSetupTypeTlv.TYPE:
                if (cb.readableBytes() != PathSetupTypeTlv.LENGTH) {
                    throw new PcepParseException("Length is not valid in PathSetupTypeTlv");
                }
                tlv = PathSetupTypeTlv.of(cb.readInt());
                break;
            default:
                throw new PcepParseException("Unsupported TLV received in SRP 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;
    }

    /**
     * Writes optional tlvs to channel buffer.
     *
     * @param cb of type channel buffer
     * @return true if writing optional tlv to channel buffer is success.
     */
    protected boolean 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);

            // 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 srp Object.
     */
    public static class Builder implements PcepSrpObject.Builder {
        private boolean bIsHeaderSet = false;
        private boolean bIsSrpIdset = false;
        private boolean bIsRFlagSet = false;

        private PcepObjectHeader srpObjHeader;
        private int srpId;
        private boolean bRFlag;
        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepSrpObject build() throws PcepParseException {
            PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;

            boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;

            if (!this.bIsSrpIdset) {
                throw new PcepParseException("SrpID not set while building SRP Object.");
            }

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

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

            return new PcepSrpObjectVer1(srpObjHeader, bRFlag, this.srpId, this.llOptionalTlv);
        }

        @Override
        public PcepObjectHeader getSrpObjHeader() {
            return this.srpObjHeader;
        }

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

        @Override
        public int getSrpID() {
            return this.srpId;
        }

        @Override
        public Builder setSrpID(int srpID) {
            this.srpId = srpID;
            this.bIsSrpIdset = true;
            return this;
        }

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

        @Override
        public Builder setRFlag(boolean bRFlag) {
            this.bRFlag = bRFlag;
            this.bIsRFlagSet = 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("RFlag", bRFlag)
                .add("SRPID", srpId)
                .add("OptionalTlvList", llOptionalTlv)
                .toString();
    }
}
