/*
 * 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.types;

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.PcepVersion;

import com.google.common.base.MoreObjects;

/**
 * Provides Pcep Rsvp User Error Spec.
 */
public class PcepRsvpUserErrorSpec implements PcepRsvpErrorSpec {

    /*
        RSVP error spec object header.
        0             1              2             3
    +-------------+-------------+-------------+-------------+
    |       Length (bytes)      |  Class-Num  |   C-Type    |
    +-------------+-------------+-------------+-------------+
    |                                                       |
    //                  (Object contents)                   //
    |                                                       |
    +-------------+-------------+-------------+-------------+

    Ref : USER_ERROR_SPEC @ RFC5284.
    USER_ERROR_SPEC object: Class = 194, C-Type = 1

    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
    +---------------+---------------+---------------+---------------+
    |                       Enterprise Number                       |
    +---------------+---------------+---------------+---------------+
    |    Sub Org    |  Err Desc Len |        User Error Value       |
    +---------------+---------------+---------------+---------------+
    |                                                               |
    ~                       Error Description                       ~
    |                                                               |
    +---------------+---------------+---------------+---------------+
    |                                                               |
    ~                     User-Defined Subobjects                   ~
    |                                                               |
    +---------------+---------------+---------------+---------------+
     */

    public static final byte CLASS_NUM = (byte) 0xc2;
    public static final byte CLASS_TYPE = 0x01;

    private PcepRsvpSpecObjHeader objHeader;
    private int enterpriseNum;
    private byte subOrg;
    private byte errDescLen;
    private short userErrorValue;
    private byte[] errDesc;
    private LinkedList<PcepValueType> llRsvpUserSpecSubObj;

    /**
     * Default constructor.
     *
     * @param objHeader pcep rsvp spec object header
     * @param enterpriseNum enterprise number
     * @param subOrg organization identifier value
     * @param errDescLen error description length
     * @param userErrorValue user error value
     * @param errDesc error description
     * @param llRsvpUserSpecSubObj list of subobjects
     */
    public PcepRsvpUserErrorSpec(PcepRsvpSpecObjHeader objHeader, int enterpriseNum, byte subOrg, byte errDescLen,
            short userErrorValue, byte[] errDesc, LinkedList<PcepValueType> llRsvpUserSpecSubObj) {
        this.objHeader = objHeader;
        this.enterpriseNum = enterpriseNum;
        this.subOrg = subOrg;
        this.errDescLen = errDescLen;
        this.userErrorValue = userErrorValue;
        this.errDesc = errDesc;
        this.llRsvpUserSpecSubObj = llRsvpUserSpecSubObj;
    }

    @Override
    public int write(ChannelBuffer cb) {
        int objLenIndex = objHeader.write(cb);
        cb.writeInt(enterpriseNum);
        cb.writeByte(subOrg);
        cb.writeByte(errDescLen);
        cb.writeShort(userErrorValue);
        cb.writeBytes(errDesc);

        if (llRsvpUserSpecSubObj != null) {

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

            while (listIterator.hasNext()) {
                PcepValueType tlv = listIterator.next();
                if (tlv == null) {
                    continue;
                }
                tlv.write(cb);
                // need to take care of padding
                int pad = tlv.getLength() % 4;
                if (0 != pad) {
                    pad = 4 - pad;
                    for (int i = 0; i < pad; ++i) {
                        cb.writeByte((byte) 0);
                    }
                }
            }
        }
        short objLen = (short) (cb.writerIndex() - objLenIndex);
        cb.setShort(objLenIndex, objLen);
        return objLen;
    }

    /**
     * Reads the channel buffer and returns object of PcepRsvpErrorSpec.
     *
     * @param cb of type channel buffer
     * @return object of PcepRsvpErrorSpec
     * @throws PcepParseException when expected object is not received
     */
    public static PcepRsvpErrorSpec read(ChannelBuffer cb) throws PcepParseException {
        PcepRsvpSpecObjHeader objHeader;
        int enterpriseNum;
        byte subOrg;
        byte errDescLen;
        short userErrorValue;
        byte[] errDesc;
        LinkedList<PcepValueType> llRsvpUserSpecSubObj = null;

        objHeader = PcepRsvpSpecObjHeader.read(cb);

        if (objHeader.getObjClassNum() != CLASS_NUM || objHeader.getObjClassType() != CLASS_TYPE) {
            throw new PcepParseException("Expected PcepRsvpUserErrorSpec object.");
        }
        enterpriseNum = cb.readInt();
        subOrg = cb.readByte();
        errDescLen = cb.readByte();
        userErrorValue = cb.readShort();
        errDesc = new byte[errDescLen];
        cb.readBytes(errDesc, 0, errDescLen);

        llRsvpUserSpecSubObj = parseErrSpecSubObj(cb);

        return new PcepRsvpUserErrorSpec(objHeader, enterpriseNum, subOrg, errDescLen, userErrorValue, errDesc,
                llRsvpUserSpecSubObj);
    }

    private static LinkedList<PcepValueType> parseErrSpecSubObj(ChannelBuffer cb) throws PcepParseException {
        LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<>();
        while (0 < cb.readableBytes()) {
            PcepValueType tlv = null;
            short hType = cb.readShort();
            int iValue = 0;
            //short hLength = cb.readShort();
            switch (hType) {
            case AutonomousSystemSubTlv.TYPE:
                iValue = cb.readInt();
                tlv = new AutonomousSystemSubTlv(iValue);
                break;
            default:
                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
            }
            llRsvpUserSpecSubObj.add(tlv);
        }
        return llRsvpUserSpecSubObj;
    }

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

    @Override
    public short getType() {
        return StatefulRsvpErrorSpecTlv.TYPE;
    }

    @Override
    public short getLength() {
        return objHeader.getObjLen();
    }

    @Override
    public byte getClassNum() {
        return CLASS_NUM;
    }

    @Override
    public byte getClassType() {
        return CLASS_TYPE;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("enterpriseNumber", enterpriseNum)
                .add("subOrganization", subOrg)
                .add("errDescLength", errDescLen)
                .add("userErrorValue", userErrorValue)
                .add("errDesc", errDesc)
                .add("RsvpUserSpecSubObject", llRsvpUserSpecSubObj)
                .toString();
    }
}
