import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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 javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.jsp.jstl.core.Config;
/**
 * (C) Copyright International Business Machines Corp.
 */

/**
 * @author ryates
 *
 */
public class ConnegFilter implements Filter{
	
	private final static String PATH_TO_REPLACE_PARAM_NAME = "path-to-replace";
	private String pathWithLanguage;
	private String pathToReplace;
	private Pattern regex;

	public void init(FilterConfig config) throws ServletException {
		pathToReplace = config.getInitParameter(PATH_TO_REPLACE_PARAM_NAME);
		pathWithLanguage = pathToReplace + "language/";	
		regex = Pattern.compile(pathWithLanguage+"(.*?)/(.*)");
	}

	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpReq = (HttpServletRequest)request;
		HttpServletResponse httpRes = (HttpServletResponse)response;
		String pathWithContextRemoved = httpReq.getRequestURI().substring(httpReq.getContextPath().length());
		if(pathWithContextRemoved.startsWith(pathWithLanguage)){			
			Matcher matcher = regex.matcher(pathWithContextRemoved);
			matcher.find();
			String language = matcher.group(1);
			String path = pathToReplace+matcher.group(2);
			Config.set(request, Config.FMT_LOCALE, language);
			httpReq.getRequestDispatcher(path).forward(request,new ResponseWrapper(httpRes, httpReq.getContextPath() + pathToReplace, httpReq.getContextPath() + pathWithLanguage+language+"/"));
		}else if(pathWithContextRemoved.startsWith(pathToReplace)) {
			httpRes.sendRedirect(httpReq.getContextPath()+pathWithLanguage+httpReq.getLocale().toString()+pathWithContextRemoved.substring(pathToReplace.length()-1));			
		}else{
			chain.doFilter(request,response);
		}
	}

	public void destroy() {
	}
	
	public class ResponseWrapper extends HttpServletResponseWrapper implements HttpServletResponse {
		
		private String replacementPath;
		private String pathToReplace;
		
		public ResponseWrapper(HttpServletResponse response, String pathToReplace, String replacementPath){
			super(response);
			this.pathToReplace = pathToReplace;
			this.replacementPath = replacementPath;
		}

		/* (non-Javadoc)
		 * @see javax.servlet.http.HttpServletResponseWrapper#encodeRedirectUrl(java.lang.String)
		 */
		public String encodeRedirectUrl(String arg0) {
			arg0 = replacePathIfNeeded(arg0);
			return super.encodeRedirectUrl(arg0);
		}

		/* (non-Javadoc)
		 * @see javax.servlet.http.HttpServletResponseWrapper#encodeRedirectURL(java.lang.String)
		 */
		public String encodeRedirectURL(String arg0) {
			arg0 = replacePathIfNeeded(arg0);
			return super.encodeRedirectURL(arg0);
		}

		/* (non-Javadoc)
		 * @see javax.servlet.http.HttpServletResponseWrapper#encodeUrl(java.lang.String)
		 */
		public String encodeUrl(String arg0) {
			arg0 = replacePathIfNeeded(arg0);
			return super.encodeUrl(arg0);
		}

		/* (non-Javadoc)
		 * @see javax.servlet.http.HttpServletResponseWrapper#encodeURL(java.lang.String)
		 */
		public String encodeURL(String arg0) {
			arg0 = replacePathIfNeeded(arg0);
			return super.encodeURL(arg0);
		}
		
		private String replacePathIfNeeded(String arg0){
			return arg0.startsWith(pathToReplace)?replacementPath + arg0.substring(pathToReplace.length()):arg0;
		}
		
		
		
		
	
		
	}
}
