/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.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();
    }
}
