/*
 * Copyright 2014 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.onlab.onos.sdnip.bgp;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class for handling the decoding of the BGP messages.
 */
class BgpFrameDecoder extends FrameDecoder {
    private static final Logger log =
        LoggerFactory.getLogger(BgpFrameDecoder.class);

    private final BgpSession bgpSession;

    /**
     * Constructor for a given BGP Session.
     *
     * @param bgpSession the BGP session state to use.
     */
    BgpFrameDecoder(BgpSession bgpSession) {
        this.bgpSession = bgpSession;
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx,
                            Channel channel,
                            ChannelBuffer buf) throws Exception {
        //
        // NOTE: If we close the channel during the decoding, we might still
        // see some incoming messages while the channel closing is completed.
        //
        if (bgpSession.isClosed()) {
            return null;
        }

        log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " +
                  "messageSize = {}",
                  ctx.getChannel().getRemoteAddress(),
                  ctx.getChannel().getLocalAddress(),
                  buf.readableBytes());

        // 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
        // (See RFC 4271, Section 4.1)
        //
        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) {
                log.debug("BGP RX Error: invalid marker {} at position {}",
                          marker[i], i);
                //
                // ERROR: Connection Not Synchronized
                //
                // Send NOTIFICATION and close the connection
                int errorCode = MessageHeaderError.ERROR_CODE;
                int errorSubcode =
                    MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
                ChannelBuffer txMessage =
                    bgpSession.prepareBgpNotification(errorCode, errorSubcode,
                                                      null);
                ctx.getChannel().write(txMessage);
                bgpSession.closeChannel(ctx);
                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)) {
            log.debug("BGP RX Error: invalid Length field {}. " +
                      "Must be between {} and {}",
                      length,
                      BgpConstants.BGP_HEADER_LENGTH,
                      BgpConstants.BGP_MESSAGE_MAX_LENGTH);
            //
            // ERROR: Bad Message Length
            //
            // Send NOTIFICATION and close the connection
            ChannelBuffer txMessage =
                bgpSession.prepareBgpNotificationBadMessageLength(length);
            ctx.getChannel().write(txMessage);
            bgpSession.closeChannel(ctx);
            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:
            bgpSession.processBgpOpen(ctx, message);
            break;
        case BgpConstants.BGP_TYPE_UPDATE:
            bgpSession.processBgpUpdate(ctx, message);
            break;
        case BgpConstants.BGP_TYPE_NOTIFICATION:
            bgpSession.processBgpNotification(ctx, message);
            break;
        case BgpConstants.BGP_TYPE_KEEPALIVE:
            bgpSession.processBgpKeepalive(ctx, message);
            break;
        default:
            //
            // ERROR: Bad Message Type
            //
            // Send NOTIFICATION and close the connection
            int errorCode = MessageHeaderError.ERROR_CODE;
            int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE;
            ChannelBuffer data = ChannelBuffers.buffer(1);
            data.writeByte(type);
            ChannelBuffer txMessage =
                bgpSession.prepareBgpNotification(errorCode, errorSubcode,
                                                  data);
            ctx.getChannel().write(txMessage);
            bgpSession.closeChannel(ctx);
            return null;
        }
        return null;
    }
}
