/*
 * 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.bgpio.types;

import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides MultiProtocolExtnCapabilityTlv.
 */
public class MultiProtocolExtnCapabilityTlv implements BgpValueType {

    /*
        0       7       15      23      31
        +-------+-------+-------+-------+
        |  AFI          | Res   |  SAFI |
        +-------+-------+-------+-------+

        Multiprotocol Extensions CAPABILITY TLV format
        REFERENCE : RFC 4760
     */
    protected static final Logger log = LoggerFactory
            .getLogger(MultiProtocolExtnCapabilityTlv.class);

    public static final byte TYPE = 1;
    public static final byte LENGTH = 4;

    private final short afi;
    private final byte res;
    private final byte safi;

    /**
     * Constructor to initialize variables.
     * @param afi Address Family Identifiers
     * @param res reserved field
     * @param safi Subsequent Address Family Identifier
     */
    public MultiProtocolExtnCapabilityTlv(short afi, byte res, byte safi) {
        this.afi = afi;
        this.res = res;
        this.safi = safi;
    }

    /**
     * Returns object of MultiProtocolExtnCapabilityTlv.
     * @param afi Address Family Identifiers
     * @param res reserved field
     * @param safi Subsequent Address Family Identifier
     * @return object of MultiProtocolExtnCapabilityTlv
     */
    public static MultiProtocolExtnCapabilityTlv of(short afi, byte res,
                                                    byte safi) {
        return new MultiProtocolExtnCapabilityTlv(afi, res, safi);
    }

    /**
     * Returns afi Address Family Identifiers value.
     * @return afi Address Family Identifiers value
     */
    public short getAFI() {
        return afi;
    }

    /**
     * Returns res reserved field value.
     * @return res reserved field value
     */
    public byte getRes() {
        return res;
    }

    /**
     * Returns safi Subsequent Address Family Identifier value.
     * @return safi Subsequent Address Family Identifier value
     */
    public byte getSAFI() {
        return safi;
    }

    @Override
    public short getType() {
        return TYPE;
    }

    @Override
    public int hashCode() {
        return Objects.hash(afi, res, safi);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof MultiProtocolExtnCapabilityTlv) {
            MultiProtocolExtnCapabilityTlv other = (MultiProtocolExtnCapabilityTlv) obj;
            return Objects.equals(this.afi, other.afi)
                    && Objects.equals(this.res, other.res)
                    && Objects.equals(this.safi, other.safi);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer cb) {
        int iLenStartIndex = cb.writerIndex();
        cb.writeByte(TYPE);
        cb.writeByte(LENGTH);

        // write afi
        cb.writeShort(afi);

        // write res
        cb.writeByte(res);

        // write safi
        cb.writeByte(safi);

        return cb.writerIndex() - iLenStartIndex;
    }

    /**
     * Reads from channel buffer and returns object of MultiprotocolCapabilityTlv.
     * @param cb of type channel buffer
     * @return object of MultiProtocolExtnCapabilityTlv
     */
    public static BgpValueType read(ChannelBuffer cb) {
        short afi = cb.readShort();
        byte res = cb.readByte();
        byte safi = cb.readByte();
        return new MultiProtocolExtnCapabilityTlv(afi, res, safi);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("Type", TYPE)
                .add("Length", LENGTH)
                .add("AFI", afi)
                .add("Reserved", res)
                .add("SAFI", safi).toString();
    }
}
