package org.onlab.onos.sdnip.bgp;

import java.util.concurrent.CountDownLatch;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.onlab.packet.IpAddress;

/**
 * Class for handling the decoding of the BGP messages at the remote
 * BGP peer session.
 */
class TestBgpPeerFrameDecoder extends FrameDecoder {
    int remoteBgpVersion;               // 1 octet
    long remoteAs;                      // 2 octets
    long remoteHoldtime;                // 2 octets
    IpAddress remoteBgpIdentifier;     // 4 octets -> IPv4 address

    final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
    final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);

    @Override
    protected Object decode(ChannelHandlerContext ctx,
                            Channel channel,
                            ChannelBuffer buf) throws Exception {
        // Test for minimum length of the BGP message
        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
            // No enough data received
            return null;
        }

        //
        // Mark the current buffer position in case we haven't received
        // the whole message.
        //
        buf.markReaderIndex();

        //
        // Read and check the BGP message Marker field: it must be all ones
        //
        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
        buf.readBytes(marker);
        for (int i = 0; i < marker.length; i++) {
            if (marker[i] != (byte) 0xff) {
                // ERROR: Connection Not Synchronized. Close the channel.
                ctx.getChannel().close();
                return null;
            }
        }

        //
        // Read and check the BGP message Length field
        //
        int length = buf.readUnsignedShort();
        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
            // ERROR: Bad Message Length. Close the channel.
            ctx.getChannel().close();
            return null;
        }

        //
        // Test whether the rest of the message is received:
        // So far we have read the Marker (16 octets) and the
        // Length (2 octets) fields.
        //
        int remainingMessageLen =
            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
        if (buf.readableBytes() < remainingMessageLen) {
            // No enough data received
            buf.resetReaderIndex();
            return null;
        }

        //
        // Read the BGP message Type field, and process based on that type
        //
        int type = buf.readUnsignedByte();
        remainingMessageLen--;      // Adjust after reading the type
        ChannelBuffer message = buf.readBytes(remainingMessageLen);

        //
        // Process the remaining of the message based on the message type
        //
        switch (type) {
        case BgpConstants.BGP_TYPE_OPEN:
            processBgpOpen(ctx, message);
            break;
        case BgpConstants.BGP_TYPE_UPDATE:
            // NOTE: Not used as part of the test, because ONOS does not
            // originate UPDATE messages.
            break;
        case BgpConstants.BGP_TYPE_NOTIFICATION:
            // NOTE: Not used as part of the testing (yet)
            break;
        case BgpConstants.BGP_TYPE_KEEPALIVE:
            processBgpKeepalive(ctx, message);
            break;
        default:
            // ERROR: Bad Message Type. Close the channel.
            ctx.getChannel().close();
            return null;
        }

        return null;
    }

    /**
     * Processes BGP OPEN message.
     *
     * @param ctx the Channel Handler Context.
     * @param message the message to process.
     */
    private void processBgpOpen(ChannelHandlerContext ctx,
                                ChannelBuffer message) {
        int minLength =
            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
        if (message.readableBytes() < minLength) {
            // ERROR: Bad Message Length. Close the channel.
            ctx.getChannel().close();
            return;
        }

        //
        // Parse the OPEN message
        //
        remoteBgpVersion = message.readUnsignedByte();
        remoteAs = message.readUnsignedShort();
        remoteHoldtime = message.readUnsignedShort();
        remoteBgpIdentifier = IpAddress.valueOf((int) message.readUnsignedInt());
        // Optional Parameters
        int optParamLen = message.readUnsignedByte();
        if (message.readableBytes() < optParamLen) {
            // ERROR: Bad Message Length. Close the channel.
            ctx.getChannel().close();
            return;
        }
        message.readBytes(optParamLen);             // NOTE: data ignored

        // BGP OPEN message successfully received
        receivedOpenMessageLatch.countDown();
    }

    /**
     * Processes BGP KEEPALIVE message.
     *
     * @param ctx the Channel Handler Context.
     * @param message the message to process.
     */
    private void processBgpKeepalive(ChannelHandlerContext ctx,
                                     ChannelBuffer message) {
        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
            // ERROR: Bad Message Length. Close the channel.
            ctx.getChannel().close();
            return;
        }
        // BGP KEEPALIVE message successfully received
        receivedKeepaliveMessageLatch.countDown();
    }
}
