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

import gov.va.med.edp.dao.ServerPackageVersionDao;
import gov.va.med.edp.dao.SiteCodeLookUpDao;
import gov.va.med.edp.dao.TrackingDao;

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

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public abstract class SiteCodeController extends AbstractController {

    public static final String MACHINE_NAME_PARAM = "machineName";
    public static final String SITE_CODE_PARAM = "siteCode";    
    public static final String MACHINE_NAME_HEADER = "EdisClientMachineName";
    
    private SiteCodeLookUpDao siteCodeDao;
	private TrackingDao trackingDao;

    private String errorViewName;
	protected ServerPackageVersionDao serverPackageVersionDao;
	
    private static Logger log = Logger.getLogger(SiteCodeController.class);
    

    protected ModelAndView createErrorModelAndView(String errorMessage) {
        ModelAndView mav = new ModelAndView(getErrorViewName());
        mav.addObject("errorMessage", errorMessage);
        return mav;
    }    
    
	public SiteCodeLookUpDao getSiteCodeDao() {
		return siteCodeDao;
	}


	public void setSiteCodeDao(SiteCodeLookUpDao siteCodeDao) {
		this.siteCodeDao = siteCodeDao;
	}


	public String getErrorViewName() {
		return errorViewName;
	}


	public void setErrorViewName(String errorViewName) {
		this.errorViewName = errorViewName;
	}
	
    protected Map buildParameterMap(HttpServletRequest request, String machineName) {
        Map params = new HashMap();
        Enumeration e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String paramName = (String) e.nextElement();
            params.put(paramName, request.getParameter(paramName));
        }
        //add the machine name that needs to be passed into M here
        params.put("machine", machineName.toUpperCase());
        debug("Parameters:" + params.toString());
        
        return params;
    }

    protected String parseCNFromHttpHeaders(String machineName){
    	if (StringUtils.hasText(machineName) && machineName.startsWith("CN=")){
    		return machineName.substring(3);
    	}
        debug("Parsed Machine Name from Http Header is:" + machineName);
    	return machineName;
    }
    
	public TrackingDao getTrackingDao() {
		return trackingDao;
	}


	public void setTrackingDao(TrackingDao trackingDao) {
		this.trackingDao = trackingDao;
	}
	
    private void debug(String s) {
    	if (logger.isDebugEnabled()){
    		logger.debug(s);
    	}
	} 	
	
	protected String getMachineNameFromUserPrincipalOrSessionOrRequest(HttpServletRequest request) throws UnrecognizedClientException {
		String machineName = "";
    	
		//first try user principal. This is for situations where we don't have a load balancer in the mix
		// this is where the client is talking directly to a weblogic server using 2-way ssl..
    	if (request.getUserPrincipal() != null){
    		machineName = request.getUserPrincipal().getName();
			debug("Machine name retrieved from user principal is:" + machineName);
    	}
		
		//then try request
		if (!StringUtils.hasText(machineName)){
			machineName = request.getParameter(MACHINE_NAME_PARAM);
			debug("Machine name retrieved from HTTP Request is:" + machineName);
		}
    	//then try the session..	
    	if (!StringUtils.hasText(machineName)){
    		machineName =(String)request.getSession().getAttribute(MACHINE_NAME_PARAM);
			debug("Machine name retrieved from HTTP Session is:" + machineName);
    	}		
    	
		if (StringUtils.hasText(machineName)){
			return machineName;
		} else {
    		throw new UnrecognizedClientException(UnrecognizedClientException.NO_MACHINE_NAME_PARAM_MESSAGE, MACHINE_NAME_PARAM);
		}
	}

	public void setServerPackageVersionDao(ServerPackageVersionDao serverPackageVersionDao) {
	    this.serverPackageVersionDao = serverPackageVersionDao;
	}	
    
	public ServerPackageVersionDao getServerPackageVersionDao() {
	    return this.serverPackageVersionDao;
	}	
	
	
}
