/*
 * 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
                    // TODO: Read open message from channel buffer.
                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
                    // TODO: Read Error message from channel buffer.
                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);
            }
        }
    }
}
