/**
 *  Copyright 2003-2007 Luck Consulting Pty Ltd
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  
 *  
 */

package com.wellpoint.benefitbuilder.common.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wellpoint.waf.common.WAFConstants;
import com.wellpoint.waf.common.WAFServiceFactory;
import com.wellpoint.waf.logging.Logger;

/**
 * The original class has been changed from its initial Version to a great extent. Only
 * a few methods from the original code base are being used.
 * @author Madhav_Bhargava
 */
public class GZipCompressionFilter implements Filter {

	private static Logger logger;

	public GZipCompressionFilter() {
	}

	static {
		logger = WAFServiceFactory.getLoggingManager().getLogger(
				GZipCompressionFilter.class.getName());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
		// Do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		// Check if the client accepts GZip encoding
		if (!isIncluded(httpRequest) && acceptsGZipEncoding(httpRequest)) {
			GZipResponseWrapper wrappedResponse = new GZipResponseWrapper(httpResponse);
			chain.doFilter(httpRequest, wrappedResponse);
			wrappedResponse.finishResponse();
		} else {
			logger.logText(WAFConstants.DEBUG,httpRequest.getRequestURL()+ ". Writing without gzip compression because the request does not accept gzip.");
			chain.doFilter(request, response);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig config) throws ServletException {
		// TODO Auto-generated method stub

	}
	
	/**
	 * Checks if the client accepts gzip encoding
	 */
	private boolean acceptsGZipEncoding(final HttpServletRequest request) {

		Enumeration encodingHeaders = request.getHeaders("Accept-Encoding");
		String hValue;
		while (encodingHeaders.hasMoreElements()) {
			hValue = (String) encodingHeaders.nextElement();
			if (hValue.indexOf("gzip") != -1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks if the request uri is an include. These cannot be gzipped.
	 */
	private boolean isIncluded(final HttpServletRequest request) {
		final String uri = (String) request
				.getAttribute("javax.servlet.include.request_uri");
		final boolean includeRequest = !(uri == null);

		if (includeRequest) {
			logger.logText(WAFConstants.WARN,request.getRequestURL()+ " resulted in an include request. This is unusable, because the response will be assembled into the overrall response. Not gzipping.");
		}
		return includeRequest;
	}

}
