/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
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 edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.FakeSelfEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep;

/**
 * TODO This is caught in the middle of the transition from LoginFormBean to LoginStatusBean.
 */
public class FakeSelfEditController extends VitroHttpServlet {
	private static final String ATTRIBUTE_LOGIN_FORM_BEAN = "loginHandler";
	private static final String ATTRIBUTE_LOGIN_STATUS_BEAN = "loginStatus";
	private static final String ATTRIBUTE_LOGIN_FORM_SAVE = "saveLoginHandler";
	private static final String ATTRIBUTE_LOGIN_STATUS_SAVE = "saveLoginStatus";

	private static final Log log = LogFactory
			.getLog(FakeSelfEditController.class.getName());

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		
		try {
			super.doGet(request, response);
			
			VitroRequest vreq = new VitroRequest(request);
			HttpSession session = request.getSession();

			if (!isAuthorized(session)) {
				redirectToLoginPage(request, response);
			} else if (vreq.getParameter("force") != null) {
				startFaking(vreq, response);
			} else if (vreq.getParameter("stopfaking") != null) {
				stopFaking(vreq, response, session);
			} else {
				showTheForm(vreq, response, session);
			}
		} catch (Exception e) {
			log.error("FakeSelfEditController could not forward to view.");
			log.error(e, e);
		}
	}

	private boolean isAuthorized(HttpSession session) {
		boolean isFakingAlready = (session.getAttribute(ATTRIBUTE_LOGIN_STATUS_SAVE) != null);
		boolean isAdmin = LoginStatusBean.getBean(session).isLoggedInAtLeast(LoginStatusBean.CURATOR);
		return isAdmin || isFakingAlready;
	}

	private void startFaking(VitroRequest vreq, HttpServletResponse response)
			throws IOException {
		HttpSession session = vreq.getSession();
		VitroRequestPrep.forceToSelfEditing(vreq);
		String id = vreq.getParameter("netid");
		FakeSelfEditingIdentifierFactory.putFakeIdInSession(id, session);

		// Remove the login bean - so we are ONLY self-editing
		moveAttribute(session, ATTRIBUTE_LOGIN_FORM_BEAN,
				ATTRIBUTE_LOGIN_FORM_SAVE);
		moveAttribute(session, ATTRIBUTE_LOGIN_STATUS_BEAN,
				ATTRIBUTE_LOGIN_STATUS_SAVE);

		response.sendRedirect(vreq.getContextPath() + Controllers.ENTITY
				+ "?netid=" + id);
	}

	private void stopFaking(VitroRequest request, HttpServletResponse response,
			HttpSession session) throws IOException {
		VitroRequestPrep.forceOutOfSelfEditing(request);
		FakeSelfEditingIdentifierFactory.clearFakeIdInSession(session);

		// Restore our original login status.
		restoreAttribute(session, ATTRIBUTE_LOGIN_FORM_BEAN,
				ATTRIBUTE_LOGIN_FORM_SAVE);
		restoreAttribute(session, ATTRIBUTE_LOGIN_STATUS_BEAN,
				ATTRIBUTE_LOGIN_STATUS_SAVE);

		response.sendRedirect(request.getContextPath() + "/");
	}

	private void showTheForm(VitroRequest request,
			HttpServletResponse response, HttpSession session)
			throws ServletException, IOException {
		// Logged in as site admin: Form not yet submitted
		request.setAttribute("msg", figureMessage(session));
		request.setAttribute("title", "Self-Edit Test");
		request.setAttribute("bodyJsp", "/admin/fakeselfedit.jsp");
		RequestDispatcher rd = request
				.getRequestDispatcher(Controllers.BASIC_JSP);
		rd.forward(request, response);
	}

	/**
	 * Check if already logged in from previous form submission
	 */
	private String figureMessage(HttpSession session) {
		String netid = FakeSelfEditingIdentifierFactory.getFakeIdFromSession(session);
		if (netid != null) {
			return "You are testing self-editing as '" + netid + "'.";
		} else {
			return "You have not configured a netid to test self-editing.";
		}
	}

	private void moveAttribute(HttpSession session,
			String realAttribute, String saveAttribute) {
		Object value = session.getAttribute(realAttribute);
		if (value != null) {
			session.setAttribute(saveAttribute, value);
			session.removeAttribute(realAttribute);
		}
	}

	private void restoreAttribute(HttpSession session,
			String realAttribute, String saveAttribute) {
		Object value = session.getAttribute(saveAttribute);
		if (value != null) {
			session.setAttribute(realAttribute, value);
			session.removeAttribute(saveAttribute);
		}
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

@@ -2182,16 +2182,94 @@
 RATOR);%0A
+%09%09log.debug(%22isFakingAlready: %22 + isFakingAlready + %22, isAdmin: %22%09+ isAdmin);%0A
 %09%09return
@@ -2297,16 +2297,16 @@
 lready;%0A
-
 %09%7D%0A%0A%09pri
@@ -2821,32 +2821,70 @@
 _STATUS_SAVE);%0A%0A
+%09%09log.debug(%22Start faking as %22 + id);%0A
 %09%09response.sendR
@@ -3420,16 +3420,45 @@
 SAVE);%0A%0A
+%09%09log.debug(%22Stop faking.%22);%0A
 %09%09respon

Add debug statements