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

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.types.PcepErrorDetailInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class PcepMessageVer1 {

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

    // version: 1.0
    static final byte WIRE_VERSION = 1;
    static final int MINIMUM_LENGTH = 4;
    static final int PACKET_VERSION = 1;
    static final byte OPEN_MSG_TYPE = 0x1;
    static final byte KEEPALIVE_MSG_TYPE = 0x2;
    static final byte REPORT_MSG_TYPE = 0xa;
    static final byte TE_REPORT_MSG_TYPE = 0xe;
    static final byte UPDATE_MSG_TYPE = 0xb;
    static final byte INITIATE_MSG_TYPE = 0xc;
    static final byte CLOSE_MSG_TYPE = 0x7;
    static final byte ERROR_MSG_TYPE = 0x6;
    static final byte LABEL_UPDATE_MSG_TYPE = 0xD;
    public static final int SHIFT_FLAG = 5;
    static final int MINIMUM_COMMON_HEADER_LENGTH = 4;

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

    static class Reader implements PcepMessageReader<PcepMessage> {
        @Override
        public PcepMessage readFrom(ChannelBuffer cb) throws PcepParseException {

            if (cb.readableBytes() < MINIMUM_LENGTH) {
                throw new PcepParseException("Packet should have minimum length: " + MINIMUM_LENGTH);
            }

            try {
                int start = cb.readerIndex();
                // fixed value property version == 1
                byte version = cb.readByte();
                version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
                if (version != (byte) PACKET_VERSION) {
                    throw new PcepParseException("Wrong version. Expected=PcepVersion.Message_1(1), got=" + version);
                }

                byte type = cb.readByte();
                short length = cb.readShort();
                cb.readerIndex(start);

                switch (type) {

                case OPEN_MSG_TYPE:
                    log.debug("OPEN MESSAGE is received");
                    // message type value 1 means it is open message
                    return PcepOpenMsgVer1.READER.readFrom(cb.readBytes(length));
                case KEEPALIVE_MSG_TYPE:
                    log.debug("KEEPALIVE MESSAGE is received");
                    // message type value 2 means it is Keepalive message
                    return PcepKeepaliveMsgVer1.READER.readFrom(cb.readBytes(length));
                case ERROR_MSG_TYPE:
                    log.debug("ERROR MESSAGE is received");
                    // message type value 6 means it is error message
                    return PcepErrorMsgVer1.READER.readFrom(cb.readBytes(length));
                case REPORT_MSG_TYPE:
                    log.debug("REPORT MESSAGE is received");
                    // message type value 10 means it is Report message
                    // return
                    // TODO: Read Report message from channel buffer.
                case UPDATE_MSG_TYPE:
                    log.debug("UPDATE MESSAGE is received");
                    //message type value 11 means it is Update message
                    return PcepUpdateMsgVer1.READER.readFrom(cb.readBytes(length));
                case INITIATE_MSG_TYPE:
                    log.debug("INITIATE MESSAGE is received");
                    //message type value 12 means it is PcInitiate message
                    return PcepInitiateMsgVer1.READER.readFrom(cb.readBytes(length));
                case CLOSE_MSG_TYPE:
                    log.debug("CLOSE MESSAGE is received");
                    // message type value 7 means it is Close message
                    return PcepCloseMsgVer1.READER.readFrom(cb.readBytes(length));
                case TE_REPORT_MSG_TYPE:
                    log.debug("TE REPORT MESSAGE is received");
                    // message type value 14 means it is TE REPORT message
                    // return
                    // TODO: Read TE Report message from channel buffer.
                case LABEL_UPDATE_MSG_TYPE:
                    log.debug("LABEL UPDATE MESSAGE is received");
                    // message type value 13 means it is LABEL UPDATE message
                    // return
                    // TODO: Read Label update message from channel buffer.
                default:
                    throw new PcepParseException("ERROR: UNKNOWN MESSAGE is received. Msg Type: " + type);
                }
            } catch (IndexOutOfBoundsException e) {
                throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_1);
            }
        }
    }
}
