/*
 * 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.PcepRroObject;
import org.onosproject.pcepio.types.IPv4SubObject;
import org.onosproject.pcepio.types.IPv6SubObject;
import org.onosproject.pcepio.types.LabelSubObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.onosproject.pcepio.types.PcepValueType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP RRO object.
 */
public class PcepRroObjectVer1 implements PcepRroObject {

    /*
     * rfc3209
          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
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |                                                               |
         //                        (Subobjects)                          //
         |                                                               |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            Each subobject has its own Length
            field.  The length contains the total length of the subobject in
            bytes, including the Type and Length fields.  The length MUST always
            be a multiple of 4, and at least 4.

            An empty RRO with no subobjects is considered illegal.
            Three kinds of subobjects are currently defined.

           Subobject 1: IPv4 address

            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
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |      Type     |     Length    | IPv4 address (4 bytes)        |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | IPv4 address (continued)      | Prefix Length |      Flags    |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Subobject 2: IPv6 address

            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
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |      Type     |     Length    | IPv6 address (16 bytes)       |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | IPv6 address (continued)                                      |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | IPv6 address (continued)                                      |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | IPv6 address (continued)                                      |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | IPv6 address (continued)      | Prefix Length |      Flags    |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Subobject 3, Label

            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
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |     Type      |     Length    |    Flags      |   C-Type      |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |       Contents of Label Object                                |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

    public static final byte RRO_OBJ_TYPE = 1;
    public static final byte RRO_OBJ_CLASS = 8;
    public static final byte RRO_OBJECT_VERSION = 1;
    public static final short RRO_OBJ_MINIMUM_LENGTH = 12;
    public static final int OBJECT_HEADER_LENGTH = 4;
    public static final int YTYPE_SHIFT_VALUE = 0x7F;

    static final PcepObjectHeader DEFAULT_RRO_OBJECT_HEADER = new PcepObjectHeader(RRO_OBJ_CLASS, RRO_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RRO_OBJ_MINIMUM_LENGTH);

    private short rroObjType = 0;
    private byte length;
    private byte prefixLength;
    private byte resvd;
    PcepObjectHeader rroObjHeader;
    private LinkedList<PcepValueType> llSubObjects = new LinkedList<>();

    /**
     * Reset variables.
     */
    public PcepRroObjectVer1() {
        this.rroObjHeader = null;
        this.rroObjType = 0;
        this.length = 0;
    }

    /**
     * constructor to initialize parameters for RRO object.
     *
     * @param rroObjHeader RRO object header
     * @param llSubObjects list of sub objects
     */
    public PcepRroObjectVer1(PcepObjectHeader rroObjHeader, LinkedList<PcepValueType> llSubObjects) {
        this.rroObjHeader = rroObjHeader;
        this.llSubObjects = llSubObjects;
    }

    /**
     * Returns PCEP RRO Object Header.
     *
     * @return rroObjHeader RRO Object header
     */
    public PcepObjectHeader getRroObjHeader() {
        return this.rroObjHeader;
    }

    /**
     * Sets PCEP RRO Object Header.
     *
     * @param obj Object header
     */
    public void setRroObjHeader(PcepObjectHeader obj) {
        this.rroObjHeader = obj;
    }

    @Override
    public LinkedList<PcepValueType> getSubObjects() {
        return this.llSubObjects;
    }

    @Override
    public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
        this.llSubObjects = llSubObjects;
    }

    /**
     * Reads the channel buffer and returns object of PcepRroObject.
     *
     * @param cb of type channel buffer
     * @return object of PcepRroObject
     * @throws PcepParseException when fails to read from channel buffer
     */
    public static PcepRroObject read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader rroObjHeader;
        LinkedList<PcepValueType> llSubObjects;
        rroObjHeader = PcepObjectHeader.read(cb);

        //take only RroObject buffer.
        ChannelBuffer tempCb = cb.readBytes(rroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
        llSubObjects = parseSubObjects(tempCb);

        return new PcepRroObjectVer1(rroObjHeader, llSubObjects);
    }

    /**
     * Returns list of sub objects.
     *
     * @param cb of type channel buffer
     * @return list of sub objects
     * @throws PcepParseException when fails to parse list of sub objects
     */
    protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {

        LinkedList<PcepValueType> llSubObjects = new LinkedList<>();

        while (0 < cb.readableBytes()) {

            //check the Type of the Sub objects
            byte yType = cb.readByte();
            yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
            byte hLength = cb.readByte();

            PcepValueType subObj;

            switch (yType) {

            case IPv4SubObject.TYPE:
                subObj = IPv4SubObject.read(cb);
                break;
            case IPv6SubObject.TYPE:
                byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
                cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
                subObj = new IPv6SubObject(ipv6Value);
                break;
            case LabelSubObject.TYPE:
                subObj = LabelSubObject.read(cb);
                break;
            default:
                throw new PcepParseException(" Unexpected sub object. Type: " + (int) yType);
            }
            // Check for the padding
            int pad = hLength % 4;
            if (0 < pad) {
                pad = 4 - pad;
                if (pad <= cb.readableBytes()) {
                    cb.skipBytes(pad);
                }
            }
            llSubObjects.add(subObj);
        }

        return llSubObjects;
    }

    @Override
    public int write(ChannelBuffer cb) throws PcepParseException {
        //write Object header
        int objStartIndex = cb.writerIndex();

        int objLenIndex = rroObjHeader.write(cb);

        if (objLenIndex <= 0) {
            throw new PcepParseException(" object Length Index" + objLenIndex);
        }

        ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();

        while (listIterator.hasNext()) {
            listIterator.next().write(cb);
        }

        //Update object length now
        int length = cb.writerIndex() - objStartIndex;
        cb.setShort(objLenIndex, (short) length);
        //will be helpful during print().
        rroObjHeader.setObjLen((short) length);

        //As per RFC the length of object should be multiples of 4
        int pad = length % 4;

        if (0 != pad) {
            pad = 4 - pad;
            for (int i = 0; i < pad; i++) {
                cb.writeByte((byte) 0);
            }
            length = length + pad;
        }
        objLenIndex = cb.writerIndex();
        return objLenIndex;
    }

    /**
     * Builder class for PCEP RRO object.
     */
    public static class Builder implements PcepRroObject.Builder {
        private boolean bIsHeaderSet = false;

        private PcepObjectHeader rroObjHeader;
        LinkedList<PcepValueType> llSubObjects = new LinkedList<>();

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepRroObject build() {

            PcepObjectHeader rroObjHeader = this.bIsHeaderSet ? this.rroObjHeader : DEFAULT_RRO_OBJECT_HEADER;

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

            if (bIsIFlagSet) {
                rroObjHeader.setIFlag(bIFlag);
            }
            return new PcepRroObjectVer1(rroObjHeader, this.llSubObjects);
        }

        @Override
        public PcepObjectHeader getRroObjHeader() {
            return this.rroObjHeader;
        }

        @Override
        public Builder setRroObjHeader(PcepObjectHeader obj) {
            this.rroObjHeader = obj;
            this.bIsHeaderSet = true;
            return this;
        }

        @Override
        public LinkedList<PcepValueType> getSubObjects() {
            return this.llSubObjects;
        }

        @Override
        public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
            this.llSubObjects = llSubObjects;
            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("SubObjects", llSubObjects)
                .toString();
    }
}
