package gov.va.vss.web.interceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections15.EnumerationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

import gov.va.vss.web.SingleConversationEnforcedCommand;
import gov.va.vss.web.conversion.interceptor.AbstractInterceptor;

@Component
public class SingleSessionConversationInterceptor extends AbstractInterceptor {
	private static final Logger log = LoggerFactory.getLogger(SingleSessionConversationInterceptor.class);

	public static final String SINGLE_SESSION_CONVERSATION_INPUT_PREFIX = "vss_ssc_";

	public static class SessionConversationInterruptedException extends Exception {
		private static final long serialVersionUID = -963632800121081942L;

	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (!"POST".equalsIgnoreCase(request.getMethod())) {
			log.debug("Request was not a POST request, skipping interceptor...");
			return true;
		}

		if (isAjax(request)) {
			log.debug("Request was an AJAX request, skipping interceptor...");
			return true;
		}
		
		log.debug("scanning session for SingleConversationEnforcedCommands to ensure codes match...");
		HttpSession session = request.getSession();

		for (String p : EnumerationUtils.toList(session.getAttributeNames())) {
			Object val = session.getAttribute(p);

			if (val instanceof SingleConversationEnforcedCommand) {
				SingleConversationEnforcedCommand c = (SingleConversationEnforcedCommand) val;

				String paramVal = request.getParameter(SINGLE_SESSION_CONVERSATION_INPUT_PREFIX + p);
				if (paramVal != null && !paramVal.equals(c.getConversationIdentifier())) {
					throw new SessionConversationInterruptedException();
				}
			}
		}

		return super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		if (!"GET".equalsIgnoreCase(request.getMethod())) {
			log.debug("Request was not a GET request, skipping interceptor...");
			return;
		}

		if (isAjax(request)) {
			log.debug("Request was an AJAX request, skipping interceptor...");
			return;
		}

		log.debug("scanning session for SingleConversationEnforcedCommands");
		HttpSession session = request.getSession();

		Map<String, String> sessionIdentifiers = new HashMap<>();
		
		EnumerationUtils.toList(session.getAttributeNames()).forEach(p -> {
			Object val = session.getAttribute((String) p);

			if (val instanceof SingleConversationEnforcedCommand) {
				SingleConversationEnforcedCommand c = (SingleConversationEnforcedCommand) val;
				String newId = c.resetConversationIdentifier();
				log.debug("Reset new conversation identifier for session attribute {}: {}", p, newId);
				sessionIdentifiers.put(SINGLE_SESSION_CONVERSATION_INPUT_PREFIX + (String) p, newId); 
			}
		});
		
		request.setAttribute("sessionConversationIdentifierMap", sessionIdentifiers);
	}

}
