package io.viper.core.server.router;


import java.net.URI;
import java.util.List;
import java.util.Map;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;

import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;


public abstract class RestRoute extends Route
{
  protected RouteHandler _handler;
  protected HttpMethod _method;

  protected RestRoute(String route, RouteHandler handler, HttpMethod method)
  {
    super(route);
    _handler = handler;
    _method = method;
  }

  public boolean isMatch(HttpRequest request)
  {
    return (super.isMatch(request) && request.getMethod().equals(_method));
  }

  @Override
  public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {

    if (!(e instanceof MessageEvent) || !(((MessageEvent) e).getMessage() instanceof HttpRequest))
    {
      super.handleUpstream(ctx, e);
      return;
    }

    HttpRequest request = (HttpRequest) ((MessageEvent) e).getMessage();

    List<String> path = RouteUtil.parsePath(request.getUri());

    Map<String, String> args = RouteUtil.extractPathArgs(_route, path);
    args.putAll(RouteUtil.extractQueryParams(new URI(request.getUri())));

    try
    {
      final RouteResponse routeResponse = _handler.exec(args);

      HttpResponse response = routeResponse.HttpResponse;

      if (response == null)
      {
        response = new DefaultHttpResponse(HTTP_1_1, OK);
        response.setContent(wrappedBuffer("{\"status\": true}".getBytes()));
      }
      else
      {
        if (response.getContent().hasArray())
        {
          if (response.getContent().array().length > 0)
          {
            setContentLength(response, response.getContent().array().length);
          }
        }
      }

      ChannelFuture writeFuture = e.getChannel().write(response);
      writeFuture.addListener(new ChannelFutureListener()
      {
        @Override
        public void operationComplete(ChannelFuture channelFuture)
          throws Exception
        {
          routeResponse.dispose();
        }
      });

      // TODO: why do we always have to close the channel?? what are we doing wrong?
      if (response.getStatus() != HttpResponseStatus.OK || !isKeepAlive(request))
      {
        writeFuture.addListener(ChannelFutureListener.CLOSE);
      }
      writeFuture.addListener(ChannelFutureListener.CLOSE);
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
}

@@ -2020,24 +2020,85 @@
 xec(args);%0A%0A
+      final Boolean keepalive = isKeepAlive(request);%0A      %0A
       HttpRe
@@ -2334,32 +2334,67 @@
    else%0A      %7B%0A
+        if (keepalive)%0A        %7B%0A  
         if (resp
@@ -2423,34 +2423,38 @@
 rray())%0A        
-%7B%0A
+  %7B%0A  
           if (re
@@ -2495,34 +2495,38 @@
  %3E 0)%0A          
-%7B%0A
+  %7B%0A  
             setC
@@ -2583,24 +2583,38 @@
 ().length);%0A
+            %7D%0A
           %7D%0A
@@ -2952,167 +2952,22 @@
     
-// TODO: why do we always have to close the channel?? what are we doing wrong?%0A      if (response.getStatus() != HttpResponseStatus.OK %7C%7C !isKeepAlive(request)
+if (!keepalive
 )%0A  
@@ -3046,68 +3046,8 @@
   %7D%0A
-      writeFuture.addListener(ChannelFutureListener.CLOSE);%0A
     

update rest response