/*
 * Copyright 2016-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.isis.io.isispacket;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.isis.controller.IsisMessage;
import org.onosproject.isis.exceptions.IsisErrorType;
import org.onosproject.isis.exceptions.IsisParseException;
import org.onosproject.isis.io.isispacket.pdu.Csnp;
import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
import org.onosproject.isis.io.isispacket.pdu.Psnp;
import org.onosproject.isis.io.util.IsisConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents ISIS message reader.
 */
public class IsisMessageReader {

    private static final Logger log = LoggerFactory.getLogger(IsisMessageReader.class);

    /**
     * Reads from ISIS packet from buffer.
     *
     * @param channelBuffer buffer
     * @return ISIS message
     * @throws IsisParseException exception
     */
    public IsisMessage readFromBuffer(ChannelBuffer channelBuffer) throws IsisParseException {

        int dataLength = channelBuffer.readableBytes();
        log.debug("IsisMessageReader::readFromBuffer Data length {}", dataLength);
        if (channelBuffer.readableBytes() < IsisConstants.PDU_LENGTH) {
            log.debug("Packet should have minimum length...");
            throw new IsisParseException(IsisErrorType.MESSAGE_HEADER_ERROR, IsisErrorType.BAD_MESSAGE_LENGTH);
        }
        IsisHeader isisHeader = getIsisHeader(channelBuffer);
        int totalLength = 0;
        IsisMessage isisMessage = null;
        switch (isisHeader.isisPduType()) {
            case L1HELLOPDU:
            case L2HELLOPDU:
                isisMessage = new L1L2HelloPdu(isisHeader);
                totalLength = channelBuffer.getShort(IsisConstants.PDULENGTHPOSITION);
                break;
            case P2PHELLOPDU:
                isisMessage = new P2PHelloPdu(isisHeader);
                totalLength = channelBuffer.getShort(IsisConstants.PDULENGTHPOSITION);
                break;
            case L1LSPDU:
            case L2LSPDU:
                isisMessage = new LsPdu(isisHeader);
                totalLength = channelBuffer.getShort(8);
                break;
            case L1CSNP:
            case L2CSNP:
                isisMessage = new Csnp(isisHeader);
                totalLength = channelBuffer.getShort(8);
                break;
            case L1PSNP:
            case L2PSNP:
                isisMessage = new Psnp(isisHeader);
                totalLength = channelBuffer.getShort(8);
                break;
            default:
                log.debug("Message Reader[Decoder] - Unknown PDU type..!!!");
                break;
        }

        if (isisMessage != null) {
            try {
                int bodyLength = totalLength - IsisConstants.COMMONHEADERLENGTH;
                isisMessage.readFrom(channelBuffer.readBytes(bodyLength));

            } catch (Exception e) {
                throw new IsisParseException(IsisErrorType.ISIS_MESSAGE_ERROR,
                                             IsisErrorType.BAD_MESSAGE);
            }

        }

        return isisMessage;
    }

    /**
     * Gets ISIS header.
     *
     * @param channelBuffer ISIS header
     * @return ISIS header
     */
    private IsisHeader getIsisHeader(ChannelBuffer channelBuffer) {

        IsisHeader isisHeader = new IsisHeader();
        isisHeader.setIrpDiscriminator(channelBuffer.readByte());
        isisHeader.setPduHeaderLength(channelBuffer.readByte());
        isisHeader.setVersion(channelBuffer.readByte());
        isisHeader.setIdLength(channelBuffer.readByte());
        isisHeader.setIsisPduType(channelBuffer.readByte());
        isisHeader.setVersion2(channelBuffer.readByte());
        isisHeader.setReserved(channelBuffer.readByte());
        isisHeader.setMaximumAreaAddresses(channelBuffer.readByte());

        return isisHeader;
    }
}