package gov.va.med.edp.web.servlet.listener;

import gov.va.med.authentication.kernel.LoginUserInfoVO;
import gov.va.med.edp.dao.SessionDao;
import gov.va.med.edp.vo.SessionVO;
import gov.va.med.edp.web.controller.SessionConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.dao.DataAccessException;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class TimeOutIntegrationSessionAttributeListener implements HttpSessionAttributeListener {
    private static final String SESSION_DAO_BEAN_NAME = "sessionDao";

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

    public void attributeAdded(HttpSessionBindingEvent event) {
        if (!event.getName().equals(LoginUserInfoVO.SESSION_KEY)) return;

        setTimeOut(event);
    }

    public void attributeRemoved(HttpSessionBindingEvent event) {
        if (!event.getName().equals(LoginUserInfoVO.SESSION_KEY)) return;
    }

    public void attributeReplaced(HttpSessionBindingEvent event) {
        if (!event.getName().equals(LoginUserInfoVO.SESSION_KEY)) return;

        setTimeOut(event);
    }

    private void setTimeOut(HttpSessionBindingEvent event) {
        LoginUserInfoVO userInfo = (LoginUserInfoVO) event.getValue();

        try {
            WebApplicationContext ac = getApplicationContext(event);
            SessionDao dao = (SessionDao) ac.getBean(SESSION_DAO_BEAN_NAME, SessionDao.class);

            SessionVO sessionInfo = dao.getSessionInfo(userInfo.getLoginStationNumber(), userInfo.getUserDuz());

            String serverPackageVersion = sessionInfo.getServerPackageVersion();
            if (log.isDebugEnabled()) log.debug("set server package version to '" + serverPackageVersion + "'");
            event.getSession().setAttribute(SessionConstants.SERVER_PACKAGE_VERSION_KEY, serverPackageVersion);

            int timeOut = sessionInfo.getMaxInactiveInterval();
            event.getSession().setMaxInactiveInterval(timeOut);
            if (log.isDebugEnabled()) log.debug("set timeout for user " + userInfo.getUserDuz() + " to " + timeOut + " seconds.");
        } catch (DataAccessException e) {
            log.error("unable to fetch session info", e);
            event.getSession().setAttribute(SessionConstants.SERVER_ERROR_KEY, e);
        }
    }

    private WebApplicationContext getApplicationContext(HttpSessionBindingEvent event) throws IllegalStateException {
        return WebApplicationContextUtils.getRequiredWebApplicationContext(event.getSession().getServletContext());
    }

}
