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

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;

public class RuntimeMultipartHttpServletRequest extends
		DefaultMultipartHttpServletRequest {
	/**
     * default logger
     */
    private static Log logger = LogFactory.getLog(RuntimeMultipartHttpServletRequest.class);

    private HashMap extraParameters = new HashMap();
    private String extraQueryString;
    private String requestURI;
    private StringBuffer requestURL;
    private String servletPath;
    private String pathInfo;

	public RuntimeMultipartHttpServletRequest(HttpServletRequest wrappedRequest,
			MultiValueMap<String, MultipartFile> mpFiles,
			Map<String, String[]> mpParams,
			String actionName,
			String queryString) {
		super(wrappedRequest, mpFiles, mpParams, null);
        this.extraQueryString = queryString;
        this.requestURI = addActionNameToURI(actionName);
        this.requestURL = new StringBuffer(addActionNameToURL(actionName));
        
//        if (StringUtils.isEmpty(wrappedRequest.getServletPath())) {
//            this.servletPath = addActionNameToPathInfo(actionName);
//            this.pathInfo = null;
//        } else {
//            this.pathInfo = wrappedRequest.getPathInfo();
//            this.servletPath = addActionNameToServletPath(actionName);
//        }
        
        if (StringUtils.isEmpty(wrappedRequest.getServletPath())) {
            this.pathInfo = addActionNameToPathInfo(actionName);
            this.servletPath = wrappedRequest.getServletPath();
        } else {
            this.pathInfo = wrappedRequest.getPathInfo();
            this.servletPath = addActionNameToServletPath(actionName);
        }
        
        if (logger.isDebugEnabled()) {
        	logger.debug("this.extraQueryString=" + this.extraQueryString);
        	logger.debug("this.requestURI is " + this.requestURI + ", was " + wrappedRequest.getRequestURI());
        	logger.debug("this.requestURL is " + this.requestURL + ", was " + wrappedRequest.getRequestURL());
        	logger.debug("this.servletPath is " + this.servletPath + ", was " + wrappedRequest.getServletPath());
        	logger.debug("this.pathInfo is " + this.pathInfo + ", was " + wrappedRequest.getPathInfo());
        }
		
	}


    public String getQueryString() {
        if (extraQueryString == null) {
            return getHttpRequest().getQueryString();
        }
        String originalQueryString = getHttpRequest().getQueryString();
        if (originalQueryString != null) {
            if (originalQueryString.indexOf("?") != -1) {
                return originalQueryString + "&" + extraQueryString;
            } else {
                return originalQueryString + "?" + extraQueryString;
            }
        }
        return extraQueryString;
    }

    public String getRequestURI() {
        return requestURI;
    }

    public StringBuffer getRequestURL() {
        return requestURL;
    }

    @Override
	public String getServletPath() {
		return servletPath;
	}

    @Override
	public String getPathInfo() {
		return pathInfo;
	}

	@Override
	public RequestDispatcher getRequestDispatcher(String path) {
		return new MockRequestDispatcher(this, path);
	}
	
    private String addActionNameToURI(String actionName) {
		return addActionNameTo(getHttpRequest().getRequestURI(), actionName);
	}

    private String addActionNameToPathInfo(String actionName) {
		return addActionNameTo(getHttpRequest().getPathInfo(), actionName);
	}

    private String addActionNameToServletPath(String actionName) {
		return addActionNameTo(getHttpRequest().getServletPath(), actionName);
	}

    private String addActionNameToURL(String actionName) {
		return addActionNameTo(getHttpRequest().getRequestURL(), actionName);
	}

	private String addActionNameTo(CharSequence uri, String actionName) {
		if (actionName == null) {
			return uri.toString();
		}
		int pos = uri.toString().lastIndexOf("/") + 1;
		return uri.subSequence(0, pos) + actionName;
	}

	public HttpServletRequest getHttpRequest() {
		return (HttpServletRequest)getRequest();
	}

}
