package gov.va.med.edp.web.controller;

import gov.va.med.authentication.kernel.LoginUserInfoVO;
import gov.va.med.edp.dao.ServerPackageVersionDao;
import gov.va.med.edp.dao.TrackingDao;
import gov.va.med.edp.vo.BigBoardDebugInfoVO;
import gov.va.med.edp.web.view.XmlView;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.support.WebContentGenerator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.Set;

public class TrackingController extends AbstractController implements InitializingBean {

    private TrackingDao trackingDao;
    private ServerPackageVersionDao serverPackageVersionDao;
    protected static final String XML_VIEW = "xmlView";

    public TrackingController() {
        setRequireSession(true);
        setSupportedMethods(new String[]{WebContentGenerator.METHOD_POST});
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(trackingDao, "trackingDao is required");
    }

    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        validateSwfID(request);
        LoginUserInfoVO userInfo = getUserInfo(request);
        String result = trackingDao.executeCommand(userInfo.getLoginStationNumber(), userInfo.getUserDuz(), buildParameterMap(request));
        if (isInitDisplayBoardCommand(request))
        result = appendSiteAndVistaLinkConnectionInfo(result, request);
        return createModelAndView(result);
    }

    private void validateSwfID(HttpServletRequest request) throws UnrecognizedClientException {
        String swfID = request.getParameter("swfID");
        if (!StringUtils.hasLength(swfID)) return;

        String ids = (String) request.getSession().getAttribute(SessionConstants.RECOGNIZED_SWF_IDS_KEY);
        Set idSet = StringUtils.commaDelimitedListToSet(ids);
        if (idSet.isEmpty()) throw new UnrecognizedClientException(UnrecognizedClientException.UNRECOGNIZED_CLIENT_MESSAGE, swfID);
        if (!idSet.contains(swfID)) throw new UnrecognizedClientException(UnrecognizedClientException.UNRECOGNIZED_CLIENT_MESSAGE, swfID);
    }

    public void setTrackingDao(TrackingDao trackingDao) {
        this.trackingDao = trackingDao;
    }

    public void setServerPackageVersionDao(ServerPackageVersionDao serverPackageVersionDao) {
        this.serverPackageVersionDao = serverPackageVersionDao;
    }    
    
    protected LoginUserInfoVO getUserInfo(HttpServletRequest request) throws NoUserInfoInSessionException {
        LoginUserInfoVO userInfo = (LoginUserInfoVO) request.getSession().getAttribute(LoginUserInfoVO.SESSION_KEY);
        if (userInfo == null) throw new NoUserInfoInSessionException();
        return userInfo;
    }

    protected ModelAndView createModelAndView(String result) {
        return new ModelAndView(XML_VIEW, XmlView.XML_FRAGMENT, result);
    }

	private boolean isInitDisplayBoardCommand(HttpServletRequest request) {
		if (request.getParameter("command").equals("initDisplayBoard")) return true;
		return false;
	}    
    
    private String appendSiteAndVistaLinkConnectionInfo(String result,HttpServletRequest request) throws Exception{
    	String stnNumber = getUserInfo(request).getLoginStationNumber();
    	BigBoardDebugInfoVO vistalinkInfo = serverPackageVersionDao.getVistaLinkConnectionInfo(stnNumber);
    	vistalinkInfo.setSiteId(stnNumber);
    	result = result.concat(vistalinkInfo.toString());
    	return result;
    }	
	
    protected Map buildParameterMap(HttpServletRequest request) {
        Map params = new HashMap();
        Enumeration e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String paramName = (String) e.nextElement();
            params.put(paramName, request.getParameter(paramName));
        }
        return params;
    }
}
