package org.jreactive.iso8583.netty.pipeline;

import com.solab.iso8583.IsoMessage;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.jreactive.iso8583.IsoMessageHandler;
import org.slf4j.Logger;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Dispatches {@link IsoMessage}s to appropriate {@link IsoMessageHandler}s based on message type.
 */
@ChannelHandler.Sharable
public class DispatchingMessageHandler extends ChannelInboundHandlerAdapter {

    private final Logger logger = getLogger(DispatchingMessageHandler.class);

    private final Map<Integer, IsoMessageHandler> messageListeners = new ConcurrentHashMap<>();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof IsoMessage) {
            IsoMessage isoMessage = (IsoMessage) msg;
            final int type = isoMessage.getType();
            final IsoMessageHandler isoMessageHandler = messageListeners.get(type);
            if (isoMessageHandler != null) {
                logger.debug("Handling IsoMessage[@type={}] with {}", type, isoMessageHandler);
                isoMessageHandler.onMessage(ctx, isoMessage);
                return;
            } else {
                logger.debug("No handler is registered for IsoMessage[@type={}]", type);
            }
        }

        super.channelRead(ctx, msg);
    }

    public void addIsoMessageHandler(IsoMessageHandler handler) {
        Objects.requireNonNull(handler);
        final int type = handler.getType();
        if (messageListeners.containsKey(type)) {
            throw new IllegalStateException("Can't register two handlers for message type: " + type);
        }
        messageListeners.put(type, handler);
    }
}

@@ -1256,16 +1256,18 @@
 e%5B@type=
+0x
 %7B%7D%5D with
@@ -1271,21 +1271,44 @@
 ith %7B%7D%22,
+ String.format(%22%2504X%22,
  type
+)
 , isoMes
@@ -1508,19 +1508,44 @@
 ype=
+0x
 %7B%7D%5D%22,
+ String.format(%22%2504X%22,
  type)
+)
 ;%0A  

Print hex message type in DispatchingMessageHandler