/*
 * 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();
    }
}
