/*
 * 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.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

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

    /*             IPV4-LSP-IDENTIFIERS 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=18             |           Length=16           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                   IPv4 Tunnel Sender Address                  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             LSP ID            |           Tunnel ID           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                        Extended Tunnel ID                     |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               IPv4 Tunnel Endpoint Address                    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

    public static final short TYPE = 18;
    public static final short LENGTH = 16;
    public static final int VALUE_LENGTH = 16;
    private final int ipv4IngressAddress;
    private final short lspId;
    private final short tunnelId;
    private final int extendedTunnelId;
    private final int ipv4EgressAddress;

    /**
     * Constructor to initialize member variables.
     *
     * @param ipv4IngressAddress ingress ipv4 address
     * @param lspId lsp id
     * @param tunnelId tunnel id
     * @param extendedTunnelId extended tunnel id
     * @param ipv4EgressAddress egress ipv4 address
     */
    public StatefulIPv4LspIdentidiersTlv(int ipv4IngressAddress, short lspId, short tunnelId, int extendedTunnelId,
            int ipv4EgressAddress) {

        this.ipv4IngressAddress = ipv4IngressAddress;
        this.lspId = lspId;
        this.tunnelId = tunnelId;
        this.extendedTunnelId = extendedTunnelId;
        this.ipv4EgressAddress = ipv4EgressAddress;
    }

    /**
     * Creates object of StatefulIPv4LspIdentidiersTlv.
     *
     * @param ipv4IngressAddress ingress ipv4 address
     * @param lspId lsp id
     * @param tunnelId tunnel id
     * @param extendedTunnelId extended tunnel id
     * @param ipv4EgressAddress egress ipv4 address
     * @return object of StatefulIPv4LspIdentidiersTlv
     */
    public static StatefulIPv4LspIdentidiersTlv of(int ipv4IngressAddress, short lspId, short tunnelId,
            int extendedTunnelId, int ipv4EgressAddress) {
        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
                ipv4EgressAddress);
    }

    /**
     * Returns tunnel id.
     *
     * @return tunnelId
     */
    public short getTunnelId() {
        return this.tunnelId;
    }

    /**
     * Returns extendedTunnelId.
     *
     * @return extendedTunnelId
     */
    public int getextendedTunnelId() {
        return this.extendedTunnelId;
    }

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

    /**
     * Returns ipv4IngressAddress.
     *
     * @return ipv4IngressAddress
     */
    public int getIpv4IngressAddress() {
        return ipv4IngressAddress;
    }

    /**
     * Returns ipv4EgressAddress.
     *
     * @return ipv4EgressAddress
     */
    public int getIpv4EgressAddress() {
        return ipv4EgressAddress;
    }

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

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

    @Override
    public int hashCode() {
        return Objects.hash(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId, ipv4EgressAddress);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof StatefulIPv4LspIdentidiersTlv) {
            StatefulIPv4LspIdentidiersTlv other = (StatefulIPv4LspIdentidiersTlv) obj;
            return Objects.equals(this.ipv4IngressAddress, other.ipv4IngressAddress)
                    && Objects.equals(this.lspId, other.lspId) && Objects.equals(this.tunnelId, other.tunnelId)
                    && Objects.equals(this.extendedTunnelId, other.extendedTunnelId)
                    && Objects.equals(this.ipv4EgressAddress, other.ipv4EgressAddress);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer c) {
        int iLenStartIndex = c.writerIndex();
        c.writeShort(TYPE);
        c.writeShort(LENGTH);
        c.writeInt(ipv4IngressAddress);
        c.writeShort(lspId);
        c.writeShort(tunnelId);
        c.writeInt(extendedTunnelId);
        c.writeInt(ipv4EgressAddress);

        return c.writerIndex() - iLenStartIndex;
    }

    /**
     * Reads the channel buffer and returns object of StatefulIPv4LspIdentidiersTlv.
     *
     * @param c of type channel buffer
     * @return object of StatefulIPv4LspIdentidiersTlv
     */
    public static PcepValueType read(ChannelBuffer c) {
        int ipv4IngressAddress = c.readInt();
        short lspId = c.readShort();
        short tunnelId = c.readShort();
        int extendedTunnelId = c.readInt();
        int ipv4EgressAddress = c.readInt();
        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
                ipv4EgressAddress);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("Type:", TYPE)
                .add("Length:", LENGTH)
                .add("Ipv4IngressAddress:", ipv4IngressAddress)
                .add("LspId:", lspId).add("TunnelId:", tunnelId)
                .add("ExtendedTunnelId:", extendedTunnelId)
                .add("Ipv4EgressAddress:", ipv4EgressAddress).toString();
    }
}
