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

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;

/**
 * Provides StatefulRsvpErrorSpecTlv.
 */
public class StatefulRsvpErrorSpecTlv implements PcepValueType {

    protected static final Logger log = LoggerFactory.getLogger(StatefulRsvpErrorSpecTlv.class);

    /*                  RSVP-ERROR-SPEC TLV format
     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
     *
     *

    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=21             |            Length (variable)  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                RSVP ERROR_SPEC or USER_ERROR_SPEC Object      +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        0             1              2             3
    +-------------+-------------+-------------+-------------+
    |       Length (bytes)      |  Class-Num  |   C-Type    |
    +-------------+-------------+-------------+-------------+
    |                                                       |
    //                  (Object contents)                   //
    |                                                       |
    +-------------+-------------+-------------+-------------+

    Ref :  ERROR_SPEC @ RFC2205

    IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
    +-------------+-------------+-------------+-------------+
    |            IPv4 Error Node Address (4 bytes)          |
    +-------------+-------------+-------------+-------------+
    |    Flags    |  Error Code |        Error Value        |
    +-------------+-------------+-------------+-------------+


    IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
    +-------------+-------------+-------------+-------------+
    |                                                       |
    +                                                       +
    |                                                       |
    +           IPv6 Error Node Address (16 bytes)          +
    |                                                       |
    +                                                       +
    |                                                       |
    +-------------+-------------+-------------+-------------+
    |    Flags    |  Error Code |        Error Value        |
    +-------------+-------------+-------------+-------------+


    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 short TYPE = 21;
    public static final int OBJECT_HEADER_LENGTH = 4;
    private short hLength;

    private final PcepRsvpErrorSpec rsvpErrSpecObj;
    private final boolean isErrSpceObjSet;

    /**
     * Constructor to initialize errSpecObj.
     *
     * @param rsvpErrSpecObj Rsvp error spec object
     */
    public StatefulRsvpErrorSpecTlv(PcepRsvpErrorSpec rsvpErrSpecObj) {
        this.rsvpErrSpecObj = rsvpErrSpecObj;
        this.isErrSpceObjSet = true;
    }

    /**
     * Returns PcepRsvpErrorSpecObject.
     *
     * @return rsvpErrSpecObj
     */
    public PcepRsvpErrorSpec getPcepRsvpErrorSpec() {
        return this.rsvpErrSpecObj;
    }

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

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

    @Override
    public short getLength() {
        return hLength;
    }

    /**
     * Reads channel buffer and returns object of StatefulRsvpErrorSpecTlv.
     *
     * @param cb of type channel buffer
     * @return object of StatefulRsvpErrorSpecTlv
     * @throws PcepParseException while parsing this tlv from channel buffer
     */
    public static PcepValueType read(ChannelBuffer cb) throws PcepParseException {

        PcepRsvpErrorSpec rsvpErrSpecObj = null;
        PcepRsvpSpecObjHeader rsvpErrSpecObjHeader;

        cb.markReaderIndex();
        rsvpErrSpecObjHeader = PcepRsvpSpecObjHeader.read(cb);
        cb.resetReaderIndex();

        if (PcepRsvpIpv4ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
                && PcepRsvpIpv4ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
            rsvpErrSpecObj = PcepRsvpIpv4ErrorSpec.read(cb);
        } else if (PcepRsvpIpv6ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
                && PcepRsvpIpv6ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
            rsvpErrSpecObj = PcepRsvpIpv6ErrorSpec.read(cb);
        } else if (PcepRsvpUserErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
                && PcepRsvpUserErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
            rsvpErrSpecObj = PcepRsvpUserErrorSpec.read(cb);
        }
        return new StatefulRsvpErrorSpecTlv(rsvpErrSpecObj);
    }

    @Override
    public int hashCode() {
        return Objects.hash(rsvpErrSpecObj.hashCode());
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof StatefulRsvpErrorSpecTlv) {
            StatefulRsvpErrorSpecTlv other = (StatefulRsvpErrorSpecTlv) obj;
            return Objects.equals(this.rsvpErrSpecObj, other.rsvpErrSpecObj);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer c) {
        int iStartIndex = c.writerIndex();
        c.writeShort(TYPE);
        int tlvLenIndex = c.writerIndex();
        hLength = 0;
        c.writeShort(hLength);
        if (isErrSpceObjSet) {
            rsvpErrSpecObj.write(c);
        }
        hLength = (short) (c.writerIndex() - iStartIndex);
        c.setShort(tlvLenIndex, (hLength - OBJECT_HEADER_LENGTH));

        return c.writerIndex() - iStartIndex;
    }

    @Override
    public String toString() {
        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());

        if (!isErrSpceObjSet) {
            toStrHelper.add("Type", TYPE).add("Length", hLength);
        } else {
            toStrHelper.add("Type", TYPE).add("Length", hLength).add("RSVPErrorSpecObject", rsvpErrSpecObj);
        }
        return toStrHelper.toString();
    }
}
