/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepMessageWriter;
import org.onosproject.pcepio.protocol.PcepReportMsg;
import org.onosproject.pcepio.protocol.PcepSrpObject;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepType;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP report message.
 */
class PcepReportMsgVer1 implements PcepReportMsg {

    // Pcep version: 1

    /*
     * The format of the PCRpt message is as follows:
     *   <PCRpt Message>        ::= <Common Header>
     *                              <state-report-list>
     *Where:
     *   <state-report-list>    ::= <state-report>[<state-report-list>]
     *   <state-report>         ::= [<SRP>]
     *                              <LSP>
     *                              <path>
     * Where:
     *   <path>                 ::= <ERO><attribute-list>[<RRO>]
     *   Where:
     *   <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
     *    where:
     *    <attribute-list>      ::=[<LSPA>]
     *                             [<BANDWIDTH>]
     *                             [<metric-list>]
     *                             [<IRO>]
     *    <metric-list>       ::=<METRIC>[<metric-list>]
     */
    private static final Logger log = LoggerFactory.getLogger(PcepReportMsgVer1.class);

    public static final byte PACKET_VERSION = 1;
    //PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+LspObjMinLen(8)
    public static final int PACKET_MINIMUM_LENGTH = 12;
    public static final PcepType MSG_TYPE = PcepType.REPORT;
    public static final byte REPORT_OBJ_TYPE = 1;
    //Optional TLV
    private LinkedList<PcepStateReport> llStateReportList;

    public static final PcepReportMsgVer1.Reader READER = new Reader();

    /**
     * Reader class for reading PCEP report message from channel buffer.
     */
    static class Reader implements PcepMessageReader<PcepReportMsg> {

        LinkedList<PcepStateReport> llStateReportList;

        @Override
        public PcepReportMsg readFrom(ChannelBuffer cb) throws PcepParseException {

            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
                throw new PcepParseException("Received packet size " + cb.readableBytes()
                        + " is less than the expected size: " + PACKET_MINIMUM_LENGTH);
            }
            llStateReportList = new LinkedList<>();
            byte version = cb.readByte();
            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);

            if (version != PACKET_VERSION) {
                throw new PcepParseException(" Invalid version: " + version);
            }

            byte type = cb.readByte();

            if (type != MSG_TYPE.getType()) {
                throw new PcepParseException("Unexpected type: " + type);
            }

            short length = cb.readShort();

            if (length < PACKET_MINIMUM_LENGTH) {
                throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: "
                        + length);
            }
            // parse state report list
            parseStateReportList(cb);
            return new PcepReportMsgVer1(llStateReportList);
        }

        // Parse State Report list
        public void parseStateReportList(ChannelBuffer cb) throws PcepParseException {

            /*
                                <state-report-list>
            Where:
                    <state-report-list>     ::= <state-report>[<state-report-list>]
                    <state-report>          ::=  [<SRP>]
                                                  <LSP>
                                                  <path>
            Where:
                    <path>                  ::= <ERO><attribute-list>[<RRO>]
            Where:
                    <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.

             */

            while (0 < cb.readableBytes()) {

                PcepStateReport pcestateReq = new PcepStateReportVer1();

                /*
                 * SRP is optional
                 * Check whether SRP Object is available, if yes store it.
                 * First read common object header and check the Object Class whether it is SRP or LSP
                 * If it is LSP then store only LSP. So, SRP is optional. then read path and store.
                 * If it is SRP then store SRP and then read LSP, path and store them.
                 */

                //mark the reader index to reset
                cb.markReaderIndex();
                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);

                byte yObjectClass = tempObjHeader.getObjClass();
                byte yObjectType = tempObjHeader.getObjType();

                //reset reader index
                cb.resetReaderIndex();
                //If SRP present then store it.
                if ((PcepSrpObjectVer1.SRP_OBJ_CLASS == yObjectClass)
                        && (PcepSrpObjectVer1.SRP_OBJ_TYPE == yObjectType)) {
                    PcepSrpObject srpObj;
                    srpObj = PcepSrpObjectVer1.read(cb);
                    pcestateReq.setSrpObject(srpObj);
                }

                //store LSP object
                PcepLspObject lspObj;
                lspObj = PcepLspObjectVer1.read(cb);
                pcestateReq.setLspObject(lspObj);

                if (cb.readableBytes() > 0) {

                    //mark the reader index to reset
                    cb.markReaderIndex();
                    tempObjHeader = PcepObjectHeader.read(cb);

                    yObjectClass = tempObjHeader.getObjClass();
                    yObjectType = tempObjHeader.getObjType();

                    //reset reader index
                    cb.resetReaderIndex();

                    if ((PcepEroObjectVer1.ERO_OBJ_CLASS == yObjectClass)
                            && (PcepEroObjectVer1.ERO_OBJ_TYPE == yObjectType)) {
                        // store path
                        PcepStateReport.PcepMsgPath msgPath = new PcepStateReportVer1().new PcepMsgPath().read(cb);
                        pcestateReq.setMsgPath(msgPath);
                    }
                }

                llStateReportList.add(pcestateReq);
            }
        }
    }

    /**
     * Constructor to initialize State Report List.
     *
     * @param llStateReportList list of type Pcep state report
     */
    PcepReportMsgVer1(LinkedList<PcepStateReport> llStateReportList) {
        this.llStateReportList = llStateReportList;
    }

    /**
     * Builder class for PCEP Report message.
     */
    static class Builder implements PcepReportMsg.Builder {
        // Pcep report message fields
        LinkedList<PcepStateReport> llStateReportList;

        @Override
        public PcepVersion getVersion() {
            return PcepVersion.PCEP_1;
        }

        @Override
        public PcepType getType() {
            return PcepType.REPORT;
        }

        @Override
        public PcepReportMsg build() {
            return new PcepReportMsgVer1(this.llStateReportList);
        }

        @Override
        public LinkedList<PcepStateReport> getStateReportList() {
            return this.llStateReportList;
        }

        @Override
        public Builder setStateReportList(LinkedList<PcepStateReport> ll) {
            this.llStateReportList = ll;
            return this;
        }
    }

    @Override
    public void writeTo(ChannelBuffer cb) throws PcepParseException {
        WRITER.write(cb, this);
    }

    static final Writer WRITER = new Writer();

    /**
     * Writer class for writing PCEP report message to channel buffer.
     */
    static class Writer implements PcepMessageWriter<PcepReportMsgVer1> {

        @Override
        public void write(ChannelBuffer cb, PcepReportMsgVer1 message) throws PcepParseException {

            int startIndex = cb.writerIndex();

            // first 3 bits set to version
            cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));

            // message type
            cb.writeByte(MSG_TYPE.getType());

            // length is length of variable message, will be updated at the end
            // Store the position of message
            // length in buffer
            int msgLenIndex = cb.writerIndex();

            cb.writeShort((short) 0);
            ListIterator<PcepStateReport> listIterator = message.llStateReportList.listIterator();

            while (listIterator.hasNext()) {

                PcepStateReport stateRpt = listIterator.next();
                PcepSrpObject srpObj = stateRpt.getSrpObject();

                //SRP object is optional
                if (srpObj != null) {
                    srpObj.write(cb);
                }

                //LSP object is mandatory
                PcepLspObject lspObj = stateRpt.getLspObject();
                if (lspObj == null) {
                    throw new PcepParseException("LSP Object is mandatory object for PcRpt message.");
                } else {
                    lspObj.write(cb);
                }

                //path is mandatory
                PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
                if (msgPath == null) {
                    throw new PcepParseException("Message path is mandatory object for PcRpt message.");
                } else {
                    msgPath.write(cb);
                }
            }

            // update message length field
            int length = cb.writerIndex() - startIndex;
            cb.setShort(msgLenIndex, (short) length);
        }
    }

    @Override
    public PcepVersion getVersion() {
        return PcepVersion.PCEP_1;
    }

    @Override
    public PcepType getType() {
        return MSG_TYPE;
    }

    @Override
    public LinkedList<PcepStateReport> getStateReportList() {
        return this.llStateReportList;
    }

    @Override
    public void setStateReportList(LinkedList<PcepStateReport> ll) {
        this.llStateReportList = ll;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("StateReportList", llStateReportList)
                .toString();
    }
}
