/*
 * Copyright 2016-present 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.store.cluster.messaging.impl;

import com.google.common.base.Charsets;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpAddress.Version;
import org.onosproject.store.cluster.messaging.Endpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * Encode InternalMessage out into a byte buffer.
 */
@Sharable
public class MessageEncoder extends MessageToByteEncoder<Object> {
// Effectively MessageToByteEncoder<InternalMessage>,
// had to specify <Object> to avoid Class Loader not being able to find some classes.

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final int preamble;

    public MessageEncoder(int preamble) {
        super();
        this.preamble = preamble;
    }


    @Override
    protected void encode(
            ChannelHandlerContext context,
            Object rawMessage,
            ByteBuf out) throws Exception {

        InternalMessage message = (InternalMessage) rawMessage;

        out.writeInt(this.preamble);

        // write time
        out.writeLong(message.time().logicalTime());
        out.writeLong(message.time().logicalCounter());

        // write message id
        out.writeLong(message.id());

        Endpoint sender = message.sender();

        IpAddress senderIp = sender.host();
        if (senderIp.version() == Version.INET) {
            out.writeByte(0);
        } else {
            out.writeByte(1);
        }
        out.writeBytes(senderIp.toOctets());

        // write sender port
        out.writeInt(sender.port());

        byte[] messageTypeBytes = message.type().getBytes(Charsets.UTF_8);

        // write length of message type
        out.writeInt(messageTypeBytes.length);

        // write message type bytes
        out.writeBytes(messageTypeBytes);

        // write message status value
        out.writeInt(message.status().ordinal());

        byte[] payload = message.payload();

        // write payload length
        out.writeInt(payload.length);

        // write payload.
        out.writeBytes(payload);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
        if (cause instanceof IOException) {
            log.debug("IOException inside channel handling pipeline.", cause);
        } else {
            log.error("non-IOException inside channel handling pipeline.", cause);
        }
        context.close();
    }

    // Effectively same result as one generated by MessageToByteEncoder<InternalMessage>
    @Override
    public final boolean acceptOutboundMessage(Object msg) throws Exception {
        return msg instanceof InternalMessage;
    }
}
