import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
import org.jboss.netty.buffer.ChannelBuffer;

import java.util.concurrent.Executors;
import java.net.InetSocketAddress;

/**
 * Test Server
 */
public class TestServer {

    public static void main(String[] args) {
        ChannelFactory factory = new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
        ServerBootstrap bootstrap = new ServerBootstrap(factory);
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline p = Channels.pipeline();
                p.addLast("framedecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                p.addLast("messagedecoder", new TestDecoder());
                p.addLast("handler", new TestHandler());
                return p;
            }
        });
        bootstrap.bind(new InetSocketAddress(33333));
    }

    /**
     * Sample decoder. Reads the length and message type fields, and then reads the data
     * using the message type field, it decides what to do with the given data. Since this is a quick
     * example, only the TEXT_MESSAGE (type code 1) is supported. When a text message is received,
     * the decoder takes the data an decodes it into a string
     */
    @ChannelPipelineCoverage("all")
    public static class TestDecoder extends OneToOneDecoder {

        // message types
        public static final int TEXT_MESSAGE = 1;

        protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
            ChannelBuffer msgBuffer = (ChannelBuffer) o;
            int msgType = msgBuffer.readInt();
            byte[] data = new byte[msgBuffer.readableBytes()];
            msgBuffer.readBytes(data);
            switch (msgType) {
                case TEXT_MESSAGE:
                    return new String(data, "UTF-8");
                default:
                    return null;
            }
        }
    }

    /**
     * Prints out text messages
     */
    @ChannelPipelineCoverage("all")
    public static class TestHandler extends SimpleChannelHandler {

        @Override
        public void messageReceived(ChannelHandlerContext channelHandlerContext, MessageEvent messageEvent) throws Exception {
            Object o = messageEvent.getMessage();
            if (o instanceof String) {
                System.out.println(o);
            }
        }
    }


}