package  org.jasig.portal;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.utils.CommonUtils;

/**
 * A simple servlet to handle deep links in guest mode.
 * 
 * To enable this servlet, insert th following lines to server.xml in your Tomcat hierarchy:
 * <servlet>
 *   <servlet-name>Guest</servlet-name>
 *   <servlet-class>org.jasig.portal.GuestServlet</servlet-class>
 * </servlet>
 * <servlet-mapping>
 *   <servlet-name>Guest</servlet-name>
 *   <url-pattern>/Guest</url-pattern>
 * </servlet-mapping>
 * Links should look like: http://server/uPortal_path/Guest?uP_fname=xxx&uPargs=yyy.
 * 
 * This class was mainly inspired by LoginServlet, where authentication stuff was removed.
 * 
 * @author Pascal Aubry (pascal.aubry@univ-rennes1.fr)
 */
public class GuestServlet extends HttpServlet {
	
	/**
	 * The serialization id.
	 */
	private static final long serialVersionUID = 4625987462075750390L;

	/**
	 * Constructor.
	 */
	public GuestServlet() {
		super();
	}
	
	/**
	 * A logger, used by this class only.
	 */
	private static final Log LOG = LogFactory.getLog(GuestServlet.class);
	
	/**
	 * A static string, used to build the real target URL.
	 */
	private static final String REDIRECT_STRING;

	static {
		String upFile = UPFileSpec.RENDER_URL_ELEMENT + UPFileSpec.PORTAL_URL_SEPARATOR 
		+ UserInstance.USER_LAYOUT_ROOT_NODE + UPFileSpec.PORTAL_URL_SEPARATOR + UPFileSpec.PORTAL_URL_SUFFIX;
		try {
			upFile = UPFileSpec.buildUPFile(
					"idempotent", UPFileSpec.RENDER_METHOD, UserInstance.USER_LAYOUT_ROOT_NODE, null, null);
		} catch (PortalException pe) {
			LOG.error("GuestServlet::static ", pe);
		}
		REDIRECT_STRING = upFile;
	}
	
	/**
	 * Process the incoming HttpServletRequest.
	 * @param request
	 * @param response
	 * @exception ServletException
	 * @exception IOException
	 */
	@Override
	public void service(
			final HttpServletRequest request, 
			final HttpServletResponse response) 
	throws ServletException, IOException {
		CommonUtils.setNoCache(response);
		String redirectTarget = null;
		
		// Call to setCharacterEncoding method should be done before any call to req.getParameter() method.
		try {
			request.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException uee) {
			LOG.error("Unable to set UTF-8 character encoding!", uee);
		}
		
	  	/* Grab the target functional name, if any, off the login request.
		 * Also any arguments for the target
	  	 * We will pass them  along after authentication.
	  	 */
	  	String targetFname = request.getParameter("uP_fname");
	  	String targetArgs = request.getParameter("uP_args");

		// Clear out the existing session for the user if they have one
//		final HttpSession s = request.getSession(false);
//		if (s != null) {
//			if (LOG.isDebugEnabled()) {	
//				LOG.debug("GuestServlet entered with existing session.  Invalidating it.");
//			}
//			s.invalidate();
//		}
		
		//  Create the user's session
		request.getSession(true);
//		if (LOG.isDebugEnabled()) {	
//			LOG.debug("Created new session");
//		}
		
		redirectTarget = request.getContextPath() + "/" +  REDIRECT_STRING;
		StringBuffer params = new StringBuffer();
		try {
			// Send the unauthenticated user back to the PortalSessionManager servlet
			redirectTarget =  request.getContextPath() + "/" + UPFileSpec.buildUPFile(
					"idempotent", UPFileSpec.RENDER_METHOD, UserInstance.USER_LAYOUT_ROOT_NODE, 
					request.getParameter("uP_targetNodeId"), null);
			if (targetFname != null) {
				redirectTarget = redirectTarget + "?uP_fname=" + URLEncoder.encode(targetFname, "UTF-8");
				if (targetArgs != null) {
					redirectTarget = redirectTarget + "&uP_args=" + URLEncoder.encode(targetArgs, "UTF-8");
				}
			}
		} catch (PortalException e) {
			//ignore
		}

		if (LOG.isDebugEnabled()) {	
			LOG.debug("GuestServlet redirecting to " + redirectTarget + params);
		}
		response.sendRedirect(redirectTarget + params);
	}

}
