/*
 * 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 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();
    }
}
