package org.onosproject.pcepio.protocol.ver1;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepAttribute;
import org.onosproject.pcepio.protocol.PcepEroObject;
import org.onosproject.pcepio.protocol.PcepMsgPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP Message PAth for update message.
 * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
 */
public class PcepMsgPathVer1 implements PcepMsgPath {

    /*
     *  <path>         ::= <ERO><attribute-list>
     */

    protected static final Logger log = LoggerFactory.getLogger(PcepMsgPathVer1.class);
    //PcepEroObject
    private PcepEroObject eroObj;
    private boolean isEroObjectSet;
    // PcepAttribute
    private PcepAttribute attrList;
    private boolean isAttributeListSet;

    /**
     * constructor to initialize objects.
     */
    public PcepMsgPathVer1() {
        eroObj = null;
        attrList = null;
        isEroObjectSet = false;
        isAttributeListSet = false;
    }

    @Override
    public PcepEroObject getEroObject() {
        return eroObj;
    }

    @Override
    public PcepAttribute getPcepAttribute() {
        return attrList;
    }

    @Override
    public void setEroObject(PcepEroObject eroObj) {
        this.eroObj = eroObj;
    }

    @Override
    public void setPcepAttribute(PcepAttribute attrList) {
        this.attrList = attrList;
    }

    /**
     * constructor to initialize member variables.
     *
     * @param eroObj pcep ero object
     * @param attrList pcep attribute
     */
    public PcepMsgPathVer1(PcepEroObject eroObj, PcepAttribute attrList) {
        this.eroObj = eroObj;
        isEroObjectSet = true;
        this.attrList = attrList;
        if (attrList == null) {
            isAttributeListSet = false;
        } else {
            isAttributeListSet = true;
        }
    }

    @Override
    public PcepMsgPath read(ChannelBuffer cb) throws PcepParseException {
        PcepEroObject eroObj;
        PcepAttribute attrList;

        eroObj = PcepEroObjectVer1.read(cb);
        attrList = PcepAttributeVer1.read(cb);

        return new PcepMsgPathVer1(eroObj, attrList);
    }

    @Override
    public int write(ChannelBuffer cb) throws PcepParseException {
        int iLenStartIndex = cb.writerIndex();

        //write Object header
        if (this.isEroObjectSet) {
            this.eroObj.write(cb);
        }
        if (this.isAttributeListSet) {
            attrList.write(cb);
        }

        return cb.writerIndex() - iLenStartIndex;
    }

    /**
     * builder class for PCEP Message path.
     */
    public static class Builder implements PcepMsgPath.Builder {

        private boolean bIsEROObjectSet = false;
        private boolean bIsPcepAttributeSet = false;

        //PCEP ERO Object
        private PcepEroObject eroObject;
        //PCEP Attribute list
        private PcepAttribute pcepAttribute;

        @Override
        public PcepMsgPath build() throws PcepParseException {

            //PCEP ERO Object
            PcepEroObject eroObject = null;
            //PCEP Attribute list
            PcepAttribute pcepAttribute = null;

            if (!this.bIsEROObjectSet) {
                throw new PcepParseException("ERO Object NOT Set while building PcepMsgPath.");
            } else {
                eroObject = this.eroObject;
            }
            if (!this.bIsPcepAttributeSet) {
                throw new PcepParseException("Pcep Attributes NOT Set while building PcepMsgPath.");
            } else {
                pcepAttribute = this.pcepAttribute;
            }

            return new PcepMsgPathVer1(eroObject, pcepAttribute);
        }

        @Override
        public PcepEroObject getEroObject() {
            return this.eroObject;
        }

        @Override
        public PcepAttribute getPcepAttribute() {
            return this.pcepAttribute;
        }

        @Override
        public Builder setEroObject(PcepEroObject eroObject) {
            this.eroObject = eroObject;
            this.bIsEROObjectSet = true;
            return this;
        }

        @Override
        public Builder setPcepAttribute(PcepAttribute pcepAttribute) {
            this.pcepAttribute = pcepAttribute;
            this.bIsPcepAttributeSet = true;
            return this;
        }

    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).add("EroObject", eroObj).add("AttributeList", attrList)
                .toString();
    }
}