/*
 * Copyright 2021-present Open Networking Foundation
 *
 * 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.onlab.packet.bmp;

import com.google.common.base.MoreObjects;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Deserializer;
import org.slf4j.Logger;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

import static org.onlab.packet.PacketUtils.checkInput;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * The per-peer header follows the common header for most BMP messages.
 * The rest of the data in a BMP message is dependent on the Message
 * Type field in the common header.
 * <p>
 * Peer Type (1 byte): Identifies the type of peer.  Currently, three
 * types of peers are identified:
 * <p>
 * *  Peer Type = 0: Global Instance Peer
 * *  Peer Type = 1: RD Instance Peer
 * *  Peer Type = 2: Local Instance Peer
 * <p>
 * o  Peer Flags (1 byte): These flags provide more information about
 * the peer.  The flags are defined as follows:
 * <p>
 * 0 1 2 3 4 5 6 7
 * +-+-+-+-+-+-+-+-+
 * |V|L|A| Reserved|
 * +-+-+-+-+-+-+-+-+
 * <p>
 * *  The V flag indicates that the Peer address is an IPv6 address.
 * For IPv4 peers, this is set to 0.
 * <p>
 * The L flag, if set to 1, indicates that the message reflects
 * the post-policy Adj-RIB-In (i.e., its path attributes reflect
 * the application of inbound policy).  It is set to 0 if the
 * message reflects the pre-policy Adj-RIB-In.  Locally sourced
 * routes also carry an L flag of 1.  See Section 5 for further
 * detail.  This flag has no significance when used with route
 * mirroring messages.
 * <p>
 * *  The A flag, if set to 1, indicates that the message is
 * formatted using the legacy 2-byte AS_PATH format.  If set to 0,
 * the message is formatted using the 4-byte AS_PATH format
 * [RFC6793].  A BMP speaker MAY choose to propagate the AS_PATH
 * information as received from its peer, or it MAY choose to
 * reformat all AS_PATH information into a 4-byte format
 * regardless of how it was received from the peer.  In the latter
 * case, AS4_PATH or AS4_AGGREGATOR path attributes SHOULD NOT be
 * sent in the BMP UPDATE message.  This flag has no significance
 * when used with route mirroring messages.
 * <p>
 * The remaining bits are reserved for future use.  They MUST be
 * transmitted as 0 and their values MUST be ignored on receipt.
 * <p>
 * Peer Distinguisher (8 bytes): Routers today can have multiple
 * instances (example: Layer 3 Virtual Private Networks (L3VPNs)
 * [RFC4364]).  This field is present to distinguish peers that
 * belong to one address domain from the other.
 * <p>
 * If the peer is a "Global Instance Peer", this field is zero-
 * filled.  If the peer is a "RD Instance Peer", it is set to the
 * route distinguisher of the particular instance the peer belongs
 * to.  If the peer is a "Local Instance Peer", it is set to a
 * unique, locally defined value.  In all cases, the effect is that
 * the combination of the Peer Type and Peer Distinguisher is
 * sufficient to disambiguate peers for which other identifying
 * information might overlap.
 * <p>
 * Peer Address: The remote IP address associated with the TCP
 * session over which the encapsulated PDU was received.  It is 4
 * bytes long if an IPv4 address is carried in this field (with the
 * 12 most significant bytes zero-filled) and 16 bytes long if an
 * IPv6 address is carried in this field.
 * <p>
 * Peer AS: The Autonomous System number of the peer from which the
 * encapsulated PDU was received.  If a 16-bit AS number is stored in
 * this field [RFC6793], it should be padded with zeroes in the 16
 * most significant bits.
 * <p>
 * Timestamp: The time when the encapsulated routes were received
 * (one may also think of this as the time when they were installed
 * in the Adj-RIB-In), expressed in seconds and microseconds since
 * midnight (zero hour), January 1, 1970 (UTC).  If zero, the time is
 * unavailable.  Precision of the timestamp is implementation-
 * dependent.
 * <p>
 * 4.3.  Initiation Message
 * <p>
 * The initiation message provides a means for the monitored router to
 * inform the monitoring station of its vendor, software version, and so
 * on.  An initiation message MUST be sent as the first message after
 * the TCP session comes up.  An initiation message MAY be sent at any
 * point thereafter, if warranted by a change on the monitored router.
 * <p>
 * The initiation message consists of the common BMP header followed by
 * two or more Information TLVs containing information
 * about the monitored router.  The sysDescr and sysName Information
 * TLVs MUST be sent, any others are optional.  The string TLV MAY be
 * included multiple times.
 */
public class BmpPeer extends BasePacket {

    /*
      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
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |   Peer Type   |  Peer Flags   |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |         Peer Distinguisher (present based on peer type)       |
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                 Peer Address (16 bytes)                       |
     ~                                                               ~
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                           Peer AS                             |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         Peer BGP ID                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                    Timestamp (seconds)                        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                  Timestamp (microseconds)                     |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     */
    public static final short PEER_HEADER_MINIMUM_LENGTH = 42;

    public static final short PEER_DISTINGUISHER = 8;
    public static final short IPV4_ADDRSZ = 4;
    public static final short IPV6_ADDRSZ = 16;

    protected byte type;

    protected byte flags;

    protected byte[] peerDistinguisher;

    protected InetAddress peerAddress;

    protected int peerAs;

    protected int peerBgpId;

    protected long seconds;

    protected long microseconds;

    private static Logger log = getLogger(BmpPeer.class);


    /**
     * Returns Peer Type.
     *
     * @return the peer type
     */
    public byte getType() {
        return type;
    }

    /**
     * Returns Peer Flag.
     *
     * @return the peer flag
     */
    public byte getFlag() {
        return flags;
    }

    /**
     * Returns Peer Distinguisher.
     *
     * @return the peer distingusiher
     */
    public byte[] getPeerDistinguisher() {
        return peerDistinguisher;
    }

    /**
     * Returns Peer IP Address.
     *
     * @return the peer ip address
     */
    public InetAddress getIntAddress() {
        return peerAddress;
    }

    /**
     * Returns Peer Autonomous System number.
     *
     * @return the peer AS number
     */
    public int getPeerAs() {
        return peerAs;
    }

    /**
     * Returns Peer Bgp Id.
     *
     * @return the bgp id
     */
    public int getPeerBgpId() {
        return peerBgpId;
    }

    /**
     * Returns timestamp in sec.
     *
     * @return the timestamp in sec
     */
    public long getSeconds() {
        return seconds;
    }

    /**
     * Returns timestamp in micro second.
     *
     * @return the timestamp in micro second
     */
    public long getMicroseconds() {
        return microseconds;
    }


    @Override
    public byte[] serialize() {
        final byte[] data = new byte[PEER_HEADER_MINIMUM_LENGTH];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.put(this.type);
        bb.put(this.flags);
        bb.put(this.peerDistinguisher);
        bb.put(this.peerAddress.getAddress());
        bb.putInt(this.peerAs);
        bb.putInt(this.peerBgpId);
        bb.putLong(this.seconds);
        bb.putLong(this.microseconds);

        return data;
    }

    public static Deserializer<BmpPeer> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, PEER_HEADER_MINIMUM_LENGTH);

            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            BmpPeer bmpPeer = new BmpPeer();

            bmpPeer.type = bb.get();
            bmpPeer.flags = bb.get();
            bmpPeer.peerDistinguisher = new byte[PEER_DISTINGUISHER];
            bb.get(bmpPeer.peerDistinguisher, 0, PEER_DISTINGUISHER);

            if ((bmpPeer.flags & 0x80) != 0x00) {
                bmpPeer.peerAddress = toInetAddress(IPV6_ADDRSZ, bb);
            } else {
                bb.position(bb.position() + (IPV6_ADDRSZ - IPV4_ADDRSZ));
                bmpPeer.peerAddress = toInetAddress(IPV4_ADDRSZ, bb);
            }

            bmpPeer.peerAs = bb.getInt();
            bmpPeer.peerBgpId = bb.getInt();
            bmpPeer.seconds = bb.getInt();
            bmpPeer.microseconds = bb.getInt();

            return bmpPeer;
        };
    }

    private static InetAddress toInetAddress(int length, ByteBuffer bb) {
        byte[] address = new byte[length];
        bb.get(address, 0, length);
        InetAddress ipAddress = null;
        try {
            ipAddress = InetAddress.getByAddress(address);
        } catch (UnknownHostException e) {
            log.error("InetAddress conversion failed");
        }

        return ipAddress;
    }

    @Override
    public String toString() {

        return MoreObjects.toStringHelper(getClass())
                .add("flags", flags)
                .add("type", type)
                .add("peerAddress", peerAddress.getHostAddress())
                .add("peerAs", peerAs)
                .add("seconds", seconds)
                .add("microseconds", microseconds)
                .toString();
    }

}
