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

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

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

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Created by IntelliJ IDEA.
 * User: zzy9v4
 * Date: 26-giu-2006
 * Time: 14.44.00
 * To change this template use File | Settings | File Templates.
 */
public class MockRequest extends HttpServletRequestWrapper {
	/**
     * default logger
     */
    private static Log logger = LogFactory.getLog(MockRequest.class);

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

    public MockRequest(HttpServletRequest wrappedRequest, String queryString, String actionName) {
        super(wrappedRequest);

        this.extraQueryString = queryString;
        this.requestURI = addActionNameToURI(actionName);
        this.requestURL = new StringBuffer(addActionNameToURL(actionName));
        
//        if (StringUtils.isEmpty(getRequest().getServletPath())) {
//            this.servletPath = addActionNameToPathInfo(actionName);
//            this.pathInfo = null;
//        } else {
//            this.pathInfo = getRequest().getPathInfo();
//            this.servletPath = addActionNameToServletPath(actionName);
//        }
        
        if (StringUtils.isEmpty(getHttpRequest().getServletPath())) {
            this.pathInfo = addActionNameToPathInfo(actionName);
            this.servletPath = getHttpRequest().getServletPath();
        } else {
            this.pathInfo = getHttpRequest().getPathInfo();
            this.servletPath = addActionNameToServletPath(actionName);
        }
        
        if (logger.isDebugEnabled()) {
        	logger.debug("this.extraQueryString=" + this.extraQueryString);
        	logger.debug("this.requestURI is " + this.requestURI + ", was " + getHttpRequest().getRequestURI());
        	logger.debug("this.requestURL is " + this.requestURL + ", was " + getHttpRequest().getRequestURL());
        	logger.debug("this.servletPath is " + this.servletPath + ", was " + getHttpRequest().getServletPath());
        	logger.debug("this.pathInfo is " + this.pathInfo + ", was " + getHttpRequest().getPathInfo());
        }
        
        // Parameters
        Map parameters = getRequest().getParameterMap();
        Iterator paramNames = parameters.keySet().iterator();

        while (paramNames.hasNext()) {
            String paramName = (String) paramNames.next();
            String[] paramValues = (String[]) parameters.get(paramName);
            this.addParameter(paramName, paramValues);
        }
    }

    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;
	}

	private void addParameter(String name, String[] values) {
        this.extraParameters.put(name, values);
    }

    public void setExtraQueryString(String extraQueryString) {
        this.extraQueryString = extraQueryString;
    }

    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;
	}

	public String getParameter(String string) {
        Object parameters = extraParameters.get(string);
        if (parameters != null) {
            String parameter = ((String[]) parameters)[0];
            if (parameter != null) {
                return parameter;
            }
        }
        return null;
    }

    public Enumeration getParameterNames() {
        return Collections.enumeration(extraParameters.keySet());
    }

    public String[] getParameterValues(String string) {
        Object ret = extraParameters.get(string);
        return ((String[]) ret);
    }

    public Map getParameterMap() {
        return extraParameters;
    }

	@Override
	public RequestDispatcher getRequestDispatcher(String path) {
		return new MockRequestDispatcher(this, path);
	}

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