package mmo.server;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;

import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.ReferenceCountUtil;
import mmo.server.message.Message;

/**
 * Created by flori on 02.02.2016.
 */
@AutoFactory
public class WebSocketMessageHandler extends ChannelDuplexHandler {
	private final ObjectReader reader;
	private final ObjectWriter writer;

	private static final Logger L = LoggerFactory.getLogger(WebSocketMessageHandler.class);

	@Inject
	public WebSocketMessageHandler(@Provided ObjectMapper mapper) {
		reader = mapper.reader(Message.class);
		writer = mapper.writerFor(Message.class);
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		if (msg instanceof TextWebSocketFrame) {
			Message m = reader.readValue(new ByteBufInputStream(((TextWebSocketFrame) msg).content()));
			L.trace("read: {}", m);
			ReferenceCountUtil.release(msg);
			ctx.fireChannelRead(m);
		} else {
			// TODO what to do in case of unexpected msg?
			L.warn("unexpected msg received: {}", msg);
		}
	}

	@Override
	public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
		// TODO why do I get messages that I do not want to receive???
		if (msg instanceof Message) {
			L.trace("writing: {}", msg);
			ctx.write(new TextWebSocketFrame(Unpooled.wrappedBuffer(writer.writeValueAsBytes(msg))), promise);
		} else {
			ctx.write(msg, promise);
		}
	}
}

@@ -14,16 +14,40 @@
 erver;%0A%0A
+import java.util.List;%0A%0A
 import j
@@ -447,54 +447,8 @@
 ed;%0A
-import io.netty.channel.ChannelDuplexHandler;%0A
 impo
@@ -510,30 +510,43 @@
 tty.
-c
 han
-nel.ChannelPromise
+dler.codec.MessageToMessageCodec
 ;%0Aim
@@ -791,28 +791,58 @@
 nds 
-ChannelDuplexHandler
+MessageToMessageCodec%3CTextWebSocketFrame, Message%3E
  %7B%0A%09
@@ -1183,30 +1183,28 @@
 e%0A%09p
-ublic void channelRead
+rotected void encode
 (Cha
@@ -1227,26 +1227,45 @@
 xt ctx, 
+Message msg, List%3C
 Object
- msg
+%3E out
 ) throws
@@ -1283,344 +1283,126 @@
 %7B%0A%09%09
-if (msg instanceof TextWebSocketFrame) %7B%0A%09%09%09Message m = reader.readValue(new ByteBufInputStream(((TextWebSocketFrame) msg).content()));%0A%09%09%09L.trace(%22read: %7B%7D%22, m);%0A%09%09%09ReferenceCountUtil.release(msg);%0A%09%09%09ctx.fireChannelRead(m);%0A%09%09%7D else %7B%0A%09%09%09// TODO what to do in case of unexpected msg?%0A%09%09%09L.warn(%22unexpected msg received: %7B%7D%22, msg);%0A%09%09%7D
+L.trace(%22writing: %7B%7D%22, msg);%0A%09%09out.add(new TextWebSocketFrame(Unpooled.wrappedBuffer(writer.writeValueAsBytes(msg))));
 %0A%09%7D%0A
@@ -1419,23 +1419,27 @@
 e%0A%09p
-ublic
+rotected
  void 
-writ
+decod
 e(Ch
@@ -1467,336 +1467,238 @@
 tx, 
-Object msg, ChannelPromise promise) throws Exception %7B%0A%09%09// TODO why do I get messages that I do not want to receive???%0A%09%09if (msg instanceof Message) %7B%0A%09%09%09L.trace(%22writing: %7B%7D%22, msg);%0A%09%09%09ctx.write(new TextWebSocketFrame(Unpooled.wrappedBuffer(writer.writeValueAsBytes(msg))), promise);%0A%09%09%7D else %7B%0A%09%09%09ctx.write(msg, promise);%0A%09%09%7D
+TextWebSocketFrame msg, List%3CObject%3E out) throws Exception %7B%0A%09%09Message m = reader.readValue(new ByteBufInputStream(((TextWebSocketFrame) msg).content()));%0A%09%09ReferenceCountUtil.release(msg);%0A%0A%09%09L.trace(%22read: %7B%7D%22, m);%0A%09%09out.add(m);
 %0A%09%7D%0A

use more suitable base class for message<->websocket conversion