package gov.va.med.esr.service.impl;

import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.service.EnvironmentParamService;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.util.InvalidConfigurationException;

import java.util.Map;

import org.apache.commons.lang.Validate;


public class EnvironmentParamServiceImpl extends AbstractComponent implements EnvironmentParamService {

	private boolean isDataClean = false;
    private boolean isSupportedSiteCheck = true;
    private String esrEnv = "";
    
    private static final String EDEV_KEY = "DEV"; 
    private static final String LOCAL_KEY = "LOC";
    private static final String PREPROD_KEY = "PRE"; 
    private static final String STAGING_KEY = "STG"; 
    private static final String SQA_KEY = "SQA"; 
    private static final String TRAINING_KEY = "TRN"; 
    
    private Map supportedSites = null;
    private Map sitesForEnvironment = null;
    
    public boolean isDataClean() {
    	return isDataClean;
    }
    
    public boolean isProdEnv() {
    	
    	return PROD_ENV.equalsIgnoreCase(esrEnv);
    }
    
    public boolean isStagingEnv() {
        return STAGING_ENV.equalsIgnoreCase(esrEnv);
    }
   
    public boolean isSqaEnv() {
        return SQA_ENV.equalsIgnoreCase(esrEnv);
    }
    
    /**
     * PreProd is the same as Troubleshooting.
     */
    public boolean isPreProdEnv() {
        return TROUBLESHOOTING_ENV.equalsIgnoreCase(esrEnv);
    }
    
    public boolean isTrainingEnv() {
        return TRAINING_ENV.equalsIgnoreCase(esrEnv);
    }
    
    public boolean isLocalEnv() {
        return LOCAL_ENV.equalsIgnoreCase(esrEnv);
    }
    
    public boolean isDevEnv() {
        return DEV_ENV.equalsIgnoreCase(esrEnv);
    }
    
	/**
	 * @param isDataClean The isDataClean to set.
	 */
	public void setIsDataClean(boolean isDataClean) {
		this.isDataClean = isDataClean;
	}
	
	/**
	 * @param esrEnv The esrEnv to set.
	 */
	public void setEsrEnv(String esrEnv) {
		this.esrEnv = esrEnv;
	}
    
    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        
        Validate.notNull(supportedSites, "supportedSites map must be configured");
        
        // If no sites defined for the environment isSupportedSiteCheck should be false
        if ((sitesForEnvironment == null || sitesForEnvironment.size() == 0) && isSupportedSiteCheck) {
            throw new InvalidConfigurationException("No supported sites defined for the " + esrEnv + " environment.  Set isSupportedSiteCheck to false.");
        }
    }
    
    /**
     * Determines if the facility is supported by the environment.
     * 
     * @param facility The facility to check against supported sites for the environment.
     */
    public boolean isSupportedFacility(VAFacility facility) {
        if (isProdEnv()) {
            return true;
        }
        // supportedInEnvironment should only be called if the check is configured
        else if (isSupportedSiteCheck) {
            return supportedInEnvironment(facility);
        }
        // The check is disabled so the facility should be used
        else {
            return true;
        }
    }
    
    /**
     * Set the sitesForEnvironment map from the supportedSites map.
     * 
     */
    private void setSitesForEnvironment() {
        if (isPreProdEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(PREPROD_KEY); 
        }
        else if (isSqaEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(SQA_KEY); 
        }
        else if (isStagingEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(STAGING_KEY); 
        }
        else if (isTrainingEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(TRAINING_KEY); 
        }
        else if (isLocalEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(LOCAL_KEY); 
        }
        else if (isDevEnv()) {
            sitesForEnvironment = (Map) supportedSites.get(EDEV_KEY); 
        }
    }
    
    /**
     * Determines if the facility is supported by the environment.
     * 
     * @param facility The facility to check against supported sites for the environment.
     */
    private boolean supportedInEnvironment(VAFacility facility) {
        if (facility == null) {
            return false;
        }
        
        if (sitesForEnvironment != null && sitesForEnvironment.containsKey(facility.getStationNumber())) {
            // If the site is supported update the emailDomainName on the facility
            String emailDomainName = (String) sitesForEnvironment.get(facility.getStationNumber());
            
            // Don't overwrite with null
            if (emailDomainName != null) {
                facility.setEmailDomainName(emailDomainName);
            }
            return true;
        }
        else {
            return false;
        }
    }
    
    /**
     * @param supportedSites A map with environment keys and maps of VistA sites as elements.
     */
    public void setSupportedSites(Map supportedSites) {
        // Construct VistaSiteInfo objects for the internal map entries?
        this.supportedSites = supportedSites;
        setSitesForEnvironment();
    }
    
    /**
     * @return Returns the supportedSites.
     */
    public Map getSupportedSites() {
        return supportedSites;
    }
    
    /**
     * @param isSupportedSiteCheckNeeded The isSupportedSiteCheckNeeded to set.
     */
    public void setIsSupportedSiteCheck(boolean isSupportedSiteCheck) {
        this.isSupportedSiteCheck = isSupportedSiteCheck;
    }
}
