/*
 * Copyright 2015-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.onosproject.bgpio.protocol.ver4;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpFactories;
import org.onosproject.bgpio.protocol.BgpMessage;
import org.onosproject.bgpio.protocol.BgpMessageReader;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpHeader;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides BGP messages.
 */
public abstract class BgpMessageVer4 {

    protected static final Logger log = LoggerFactory.getLogger(BgpFactories.class);

    static final byte OPEN_MSG_TYPE = 0x1;
    static final byte KEEPALIVE_MSG_TYPE = 0x4;
    static final byte UPDATE_MSG_TYPE = 0x2;
    static final byte NOTIFICATION_MSG_TYPE = 0x3;
    static final int MINIMUM_COMMON_HEADER_LENGTH = 19;
    static final int HEADER_AND_MSG_LEN = 18;
    static final int MAXIMUM_PACKET_LENGTH = 4096;

    public static final BgpMessageVer4.Reader READER = new Reader();

    /**
     * Reader class for reading BGP messages from channel buffer.
     *
     */
    static class Reader implements BgpMessageReader<BgpMessage> {
        @Override
        public BgpMessage readFrom(ChannelBuffer cb, BgpHeader bgpHeader)
                throws BgpParseException {

            if (cb.readableBytes() < MINIMUM_COMMON_HEADER_LENGTH) {
                log.error("Packet should have minimum length.");
                Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH,
                                       cb.readableBytes());
            }
            if (cb.readableBytes() > MAXIMUM_PACKET_LENGTH) {
                log.error("Packet length should not exceed {}.", MAXIMUM_PACKET_LENGTH);
                Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH,
                                       cb.readableBytes());
            }
            try {
                // fixed value property version == 4
                byte[] marker = new byte[BgpHeader.MARKER_LENGTH];
                cb.readBytes(marker, 0, BgpHeader.MARKER_LENGTH);
                bgpHeader.setMarker(marker);
                for (int i = 0; i < BgpHeader.MARKER_LENGTH; i++) {
                    if (marker[i] != (byte) 0xff) {
                        throw new BgpParseException(BgpErrorType.MESSAGE_HEADER_ERROR,
                                                    BgpErrorType.CONNECTION_NOT_SYNCHRONIZED, null);
                    }
                }
                short length = cb.readShort();
                if (length > cb.readableBytes() + HEADER_AND_MSG_LEN) {
                    Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR,
                                           BgpErrorType.BAD_MESSAGE_LENGTH, length);
                }
                bgpHeader.setLength(length);
                byte type = cb.readByte();
                bgpHeader.setType(type);
                log.debug("Reading update message of type " + type);

                int len = length - MINIMUM_COMMON_HEADER_LENGTH;
                switch (type) {
                case OPEN_MSG_TYPE:
                    log.debug("OPEN MESSAGE is received");
                    return BgpOpenMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader);
                case KEEPALIVE_MSG_TYPE:
                    log.debug("KEEPALIVE MESSAGE is received");
                    return BgpKeepaliveMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader);
                case UPDATE_MSG_TYPE:
                    log.debug("UPDATE MESSAGE is received");
                    return BgpUpdateMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader);
                case NOTIFICATION_MSG_TYPE:
                    log.debug("NOTIFICATION MESSAGE is received");
                    return BgpNotificationMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader);
                default:
                    Validation.validateType(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_TYPE, type);
                    return null;
                }
            } catch (IndexOutOfBoundsException e) {
                throw new BgpParseException(BgpErrorType.MESSAGE_HEADER_ERROR,
                                            BgpErrorType.BAD_MESSAGE_LENGTH, null);
            }
        }
    }
}