/*
 * 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 java.util.LinkedList;
import java.util.ListIterator;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepLabelUpdate;
import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepMessageWriter;
import org.onosproject.pcepio.protocol.PcepType;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

class PcepLabelUpdateMsgVer1 implements PcepLabelUpdateMsg {

    // Pcep version: 1

    /*
      The format of the PCLabelUpd message:

                  <PCLabelUpd Message>         ::=     <Common Header>
                                                       <pce-label-update-list>
                Where:

                <pce-label-update-list>        ::=     <pce-label-update>
                                                       [<pce-label-update-list>]
                <pce-label-update>             ::=     (<pce-label-download>|<pce-label-map>)

                Where:
                <pce-label-download>           ::=      <SRP>
                                                        <LSP>
                                                        <label-list>

                <pce-label-map>                 ::=     <SRP>
                                                        <LABEL>
                                                        <FEC>

                <label-list >                   ::=     <LABEL>
                                                        [<label-list>]

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

    public static final byte PACKET_VERSION = 1;

    //LabelUpdateMsgMinLength = COMMON-HEADER(4)+SrpObjMinLentgh(12)+LabelObjectMinLength(12)+FECType1Object(8)
    public static final int PACKET_MINIMUM_LENGTH = 36;
    public static final PcepType MSG_TYPE = PcepType.LABEL_UPDATE;
    //pce-label-update-list
    private LinkedList<PcepLabelUpdate> llPcLabelUpdateList;

    static final PcepLabelUpdateMsgVer1.Reader READER = new Reader();

    //Reader reads LabelUpdate Message from the channel.
    static class Reader implements PcepMessageReader<PcepLabelUpdateMsg> {

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

            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
                throw new PcepParseException("Readable bytes are less than Packet minimum length.");
            }

            // fixed value property version == 1
            byte version = cb.readByte();
            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
            if (version != PACKET_VERSION) {
                throw new PcepParseException("Wrong version.Expected=PcepVersion.PCEP_1(1), got=" + version);
            }
            // fixed value property type == 13
            byte type = cb.readByte();
            if (type != MSG_TYPE.getType()) {
                throw new PcepParseException("Wrong type. Expected=PcepType.LABEL_UPDATE(13), got=" + type);
            }
            short length = cb.readShort();
            if (length < PACKET_MINIMUM_LENGTH) {
                throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", is: "
                        + length);
            }
            // parse <pce-label-download> / <pce-label-map>
            LinkedList<PcepLabelUpdate> llPcLabelUpdateList = parsePcLabelUpdateList(cb);
            return new PcepLabelUpdateMsgVer1(llPcLabelUpdateList);
        }

        /**
         * Returns list of PCEP Label Update object.
         *
         * @param cb of type channel buffer
         * @return llPcLabelUpdateList list of PCEP label update object
         * @throws PcepParseException when fails to parse list of PCEP label update object
         */
        public LinkedList<PcepLabelUpdate> parsePcLabelUpdateList(ChannelBuffer cb) throws PcepParseException {

            LinkedList<PcepLabelUpdate> llPcLabelUpdateList;
            llPcLabelUpdateList = new LinkedList<PcepLabelUpdate>();

            while (0 < cb.readableBytes()) {
                llPcLabelUpdateList.add(PcepLabelUpdateVer1.read(cb));
            }
            return llPcLabelUpdateList;
        }
    }

    /**
     * Constructor to initialize PCEP Label Update List.
     *
     * @param llPcLabelUpdateList list of PCEP Label Update object
     */
    PcepLabelUpdateMsgVer1(LinkedList<PcepLabelUpdate> llPcLabelUpdateList) {
        this.llPcLabelUpdateList = llPcLabelUpdateList;
    }

    static class Builder implements PcepLabelUpdateMsg.Builder {

        LinkedList<PcepLabelUpdate> llPcLabelUpdateList;

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

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

        @Override
        public PcepLabelUpdateMsg build() {
            return new PcepLabelUpdateMsgVer1(this.llPcLabelUpdateList);
        }

        @Override
        public LinkedList<PcepLabelUpdate> getPcLabelUpdateList() {
            return this.llPcLabelUpdateList;
        }

        @Override
        public Builder setPcLabelUpdateList(LinkedList<PcepLabelUpdate> ll) {
            this.llPcLabelUpdateList = ll;
            return this;
        }
    }

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

    static final Writer WRITER = new Writer();

    //Writer writes LabelUpdate Message to the channel.
    static class Writer implements PcepMessageWriter<PcepLabelUpdateMsgVer1> {

        @Override
        public void write(ChannelBuffer cb, PcepLabelUpdateMsgVer1 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 will be set after calculating length, but currently set it as 0.
            int msgLenIndex = cb.writerIndex();

            cb.writeShort((short) 0);
            ListIterator<PcepLabelUpdate> listIterator = message.llPcLabelUpdateList.listIterator();

            while (listIterator.hasNext()) {
                PcepLabelUpdate labelUpdate = listIterator.next();
                labelUpdate.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<PcepLabelUpdate> getPcLabelUpdateList() {
        return this.llPcLabelUpdateList;
    }

    @Override
    public void setPcLabelUpdateList(LinkedList<PcepLabelUpdate> ll) {
        this.llPcLabelUpdateList = ll;
    }

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