package ro.isdc.wro.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.http.support.HttpHeader;
import ro.isdc.wro.model.resource.locator.support.DispatcherStreamLocator;
import ro.isdc.wro.util.WroUtil;


/**
 * A filter responsible for gzipping all content served through this filter.
 *
 * @author Alex Objelean
 * @created 11 Apr 2013
 * @since 1.6.4
 */
public class GzipFilter
    implements Filter {
  private static final Logger LOG = LoggerFactory.getLogger(GzipFilter.class);

  /**
   * {@inheritDoc}
   */
  public void init(final FilterConfig arg0)
      throws ServletException {
  }

  /**
   * {@inheritDoc}
   */
  public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
      throws IOException, ServletException {
    final HttpServletRequest request = (HttpServletRequest) req;
    final ServletResponseWrapper response = decorateResponse((HttpServletResponse) res, request);
    chain.doFilter(request, response);
    IOUtils.closeQuietly(response.getOutputStream());
  }

  private ServletResponseWrapper decorateResponse(final HttpServletResponse response, final HttpServletRequest request)
      throws IOException {
    ServletResponseWrapper wrappedResponse = new ServletResponseWrapper(response);
    if (isGzipAllowed(request)) {
      response.setHeader(HttpHeader.CONTENT_ENCODING.toString(), "gzip");
      // Create a gzip stream
      final GZIPOutputStream gzout = new GZIPOutputStream(new ByteArrayOutputStream());
      // Handle the request

      wrappedResponse = new ServletResponseWrapper(wrappedResponse) {
        @Override
        public ServletOutputStream getOutputStream()
            throws IOException {
          return super.getOutputStream();
        }
      };
      gzout.close();
    }
    return wrappedResponse;
  }

  /**
   * Checks if the request supports gzip and is not a include request (these cannot be gzipped)
   */
  protected boolean isGzipAllowed(final HttpServletRequest request) {
    return !DispatcherStreamLocator.isIncludedRequest(request) && WroUtil.isGzipSupported(request);
  }

  /**
   * {@inheritDoc}
   */
  public void destroy() {
  }

}

@@ -615,16 +615,79 @@
 ctory;%0A%0A
+import ro.isdc.wro.http.support.DelegatingServletOutputStream;%0A
 import r
@@ -1406,73 +1406,8 @@
 n %7B%0A
-    final HttpServletRequest request = (HttpServletRequest) req;%0A
     
@@ -1463,16 +1463,42 @@
 esponse(
+(HttpServletRequest) req, 
 (HttpSer
@@ -1518,17 +1518,8 @@
  res
-, request
 );%0A 
@@ -1539,20 +1539,16 @@
 lter(req
-uest
 , respon
@@ -1611,16 +1611,121 @@
 );%0A  %7D%0A%0A
+  /**%0A   * Decorates the provided %7B@link HttpServletResponse%7D which handles gzip if it is allowed.%0A   */%0A
   privat
@@ -1789,23 +1789,21 @@
 etRe
-sponse response
+quest request
 , fi
@@ -1819,29 +1819,31 @@
 ervletRe
-quest request
+sponse response
 )%0A      
@@ -1976,24 +1976,64 @@
 request)) %7B%0A
+      LOG.debug(%22setting gzip header%22);%0A
       respon
@@ -2436,15 +2436,27 @@
 urn 
-super.g
+new DelegatingServl
 etOu
@@ -2466,16 +2466,21 @@
 tStream(
+gzout
 );%0A     
@@ -2497,29 +2497,8 @@
  %7D;%0A
-      gzout.close();%0A
     

update javadoc and return gziped output stream from responseWrapper