package it.mice.voila.runtime.web.filter;

import java.io.IOException;

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 org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartHttpServletRequest;

/**
 * Created by IntelliJ IDEA.
 * User: zzy9v4
 * Date: 26-giu-2006
 * Time: 15.24.51
 * To change this template use File | Settings | File Templates.
 */
public class SubmitButtonFilter implements Filter {
    public static final String BUTTON_SUBMIT_PREFIX = "button.submit.";
    /**
     * Logger.
     */
    private Log log;

    /**
     * Force response buffering. Enabled by default.
     */
    private static String submitButtonPrefixName;

    /**
     * {@inheritDoc}
     */
    public void init(FilterConfig filterConfig)
    {
        log = LogFactory.getLog(SubmitButtonFilter.class);

        setSubmitButtonPrefixName(filterConfig.getInitParameter("submitButtonPrefixName"));
        if (getSubmitButtonPrefixName() == null) {
            setSubmitButtonPrefixName(BUTTON_SUBMIT_PREFIX);
            if (log.isDebugEnabled()) {
                log.debug("submitButtonPrefixName filter config parameter not specified. Assumed default:" + BUTTON_SUBMIT_PREFIX);
            }
        }
        log.info("Filter initialized. SubmitButtonPrefixName=" + getSubmitButtonPrefixName());
    }

    /**
     * {@inheritDoc}
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException
    {
    	RuntimeMultipartResolver resolver = null;
        Object alreadyFilteredFlag = servletRequest.getAttribute("jfAlreadyFilteredFlag");
        // la request da passare al prossimo filtro della catena
        ServletRequest servletRequestForNextFilter = servletRequest;
        if (alreadyFilteredFlag == null) {
            String submitButtonParameterName;
	        if (ServletFileUpload.isMultipartContent((HttpServletRequest)servletRequest)) {
	        	resolver = new RuntimeMultipartResolver();
	        	servletRequestForNextFilter = resolver.resolveMultipart((HttpServletRequest)servletRequest, getSubmitButtonPrefixName());
	        } else {
				submitButtonParameterName = RequestUtils.findSubmitButtonParameterName((HttpServletRequest)servletRequest, getSubmitButtonPrefixName());
	            if (submitButtonParameterName != null) {
	                if (log.isDebugEnabled()) {
	                    log.debug("Button submit:" + submitButtonParameterName + " found.");
	                }
	                servletRequestForNextFilter = prepareMockRequest((HttpServletRequest)servletRequest, submitButtonParameterName);
	            }
	        }
            servletRequest.setAttribute("jfAlreadyFilteredFlag", Boolean.TRUE);
        }
		try {
			filterChain.doFilter(servletRequestForNextFilter, servletResponse);
		}
		finally {
			if (servletRequestForNextFilter instanceof MultipartHttpServletRequest && resolver != null) {
				resolver.cleanupMultipart((MultipartHttpServletRequest) servletRequestForNextFilter);
			}
		}
    }

    private MockRequest prepareMockRequest(HttpServletRequest servletRequest, String submitButtonParameterName) {
        int endIndex = submitButtonParameterName.indexOf("?");
        String methodName;
        String queryString = null;
        if (endIndex == -1) {
            methodName = submitButtonParameterName.substring(getSubmitButtonPrefixName().length());
        } else {
            methodName = submitButtonParameterName.substring(getSubmitButtonPrefixName().length(), endIndex);
            queryString = submitButtonParameterName.substring(endIndex + 1);
        }
        if (log.isDebugEnabled()) {
            log.debug("Button submit parsed. methodName=" + methodName + "; queryString=" + queryString);
        }
        MockRequest mockRequest = new MockRequest(servletRequest, queryString, methodName);
        //mockRequest.getParameterMap().put("jfmn", new String[] {methodName});
        if (queryString != null) {
            mockRequest.getParameterMap().putAll(RequestUtils.convertToParameterMap(queryString));
        }

        return mockRequest;
    }

    public static String getSubmitButtonPrefixName() {
		return submitButtonPrefixName;
	}

	public static void setSubmitButtonPrefixName(String submitButtonPrefixName) {
		SubmitButtonFilter.submitButtonPrefixName = submitButtonPrefixName;
	}

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