/*
 * 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 org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepBandwidthObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PcepBandwidthObject.
 */
public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {

    /*
     *    RFC : 5440 , section : 7.7.
          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
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                         Bandwidth                             |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         The BANDWIDTH Object format
     */

    protected static final Logger log = LoggerFactory.getLogger(PcepBandwidthObjectVer1.class);
    /*
     *  Requested bandwidth: BANDWIDTH Object-Type is 1.
        Bandwidth of an existing TE LSP for which a re-optimization is
        requested. BANDWIDTH Object-Type is 2.
     */
    //Right now handling type 1
    public static final byte BANDWIDTH_OBJ_TYPE = 1;
    public static final byte BANDWIDTH_OBJ_CLASS = 5;
    public static final byte BANDWIDTH_OBJECT_VERSION = 1;
    public static final short BANDWIDTH_OBJ_MINIMUM_LENGTH = 8;

    static final PcepObjectHeader DEFAULT_BANDWIDTH_OBJECT_HEADER = new PcepObjectHeader(BANDWIDTH_OBJ_CLASS,
            BANDWIDTH_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
            BANDWIDTH_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader bandwidthObjHeader;
    private int iBandwidth;

    /**
     * Constructor to bandwidth object header and bandwidth.
     *
     * @param bandwidthObjHeader bandwidth object header
     * @param iBandwidth bandwidth value
     */
    public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, int iBandwidth) {
        this.bandwidthObjHeader = bandwidthObjHeader;
        this.iBandwidth = iBandwidth;
    }

    /**
     * Constructor to initialize bandwidth.
     *
     * @param iBandwidth bandwidth value
     */
    public PcepBandwidthObjectVer1(int iBandwidth) {
        this.bandwidthObjHeader = DEFAULT_BANDWIDTH_OBJECT_HEADER;
        this.iBandwidth = iBandwidth;
    }

    /**
     * Returns Object Header.
     *
     * @return bandwidthObjHeader
     */
    public PcepObjectHeader getBandwidthObjHeader() {
        return this.bandwidthObjHeader;
    }

    /**
     * Sets Object Header.
     *
     * @param obj bandwidth object header
     */
    public void setBandwidthObjHeader(PcepObjectHeader obj) {
        this.bandwidthObjHeader = obj;
    }

    @Override
    public int getBandwidth() {
        return this.iBandwidth;
    }

    @Override
    public void setBandwidth(int iBandwidth) {
        this.iBandwidth = iBandwidth;
    }

    /**
     * Reads from channel buffer and returns object of PcepBandwidthObject.
     *
     * @param cb channel buffer to parse
     * @return object of PcepBandwidthObject
     * @throws PcepParseException while parsing channel buffer
     */
    public static PcepBandwidthObject read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader bandwidthObjHeader;
        int iBandwidth;

        bandwidthObjHeader = PcepObjectHeader.read(cb);
        iBandwidth = cb.readInt();

        return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth);
    }

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

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

        if (objLenIndex <= 0) {
            throw new PcepParseException("Failed to write bandwidth object header. Index " + objLenIndex);
        }

        cb.writeInt(iBandwidth);
        short hLength = (short) (cb.writerIndex() - objStartIndex);
        cb.setShort(objLenIndex, hLength);
        //will be helpful during print().
        bandwidthObjHeader.setObjLen(hLength);

        return cb.writerIndex() - objStartIndex;
    }

    /**
     * builder class for PCEP bandwidth object.
     */
    public static class Builder implements PcepBandwidthObject.Builder {

        private PcepObjectHeader bandwidthObjHeader;
        private boolean bIsHeaderSet = false;

        private int iBandwidth;
        private boolean bIsBandwidthSet = false;

        private boolean bPFlag;
        private boolean bIsPFlagSet = false;

        private boolean bIFlag;
        private boolean bIsIFlagSet = false;

        @Override
        public PcepBandwidthObject build() throws PcepParseException {

            PcepObjectHeader bandwidthObjHeader = this.bIsHeaderSet ? this.bandwidthObjHeader
                    : DEFAULT_BANDWIDTH_OBJECT_HEADER;

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

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

            if (!this.bIsBandwidthSet) {
                throw new PcepParseException("bandwidth not Set while building Bandwidth Object.");
            }

            return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth);
        }

        @Override
        public int getBandwidth() {
            return this.iBandwidth;
        }

        @Override
        public PcepObjectHeader getBandwidthObjHeader() {
            return this.bandwidthObjHeader;
        }

        @Override
        public Builder setBandwidthObjHeader(PcepObjectHeader obj) {
            this.bandwidthObjHeader = obj;
            return this;
        }

        @Override
        public Builder setBandwidth(int iBandwidth) {
            this.iBandwidth = iBandwidth;
            this.bIsBandwidthSet = 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("BandwidthObjectHeader", bandwidthObjHeader)
                .add("Bandwidth", iBandwidth).toString();
    }
}
