/********************************************************************
 * Copyright © 2006 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.common.report.data.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;

import gov.va.med.fw.report.ReportConfiguration;
import gov.va.med.fw.report.data.QueryCriteria;
import gov.va.med.fw.report.data.ReportDataException;



import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.ReportFacilityDisplayBy;
import gov.va.med.esr.common.model.lookup.ReportFormat;
import gov.va.med.esr.common.model.lookup.VAFacility;

import gov.va.med.esr.common.model.report.ReportEnrollmentPriorityGroup;
import gov.va.med.esr.common.model.report.ReportEnrollmentStatus;
import gov.va.med.esr.common.model.report.ReportFacility;
import gov.va.med.esr.common.model.report.ReportParameterSet;
import gov.va.med.esr.common.model.report.ReportSetup;
import gov.va.med.esr.common.report.data.CommonCriteria;
import gov.va.med.esr.common.report.data.StandardReportCriteria;

/**
 * @author DNS   KULLAV	
 *
 */
public class EnrolleeEnrollmentStatusReportDataDAOImpl extends
		AbstractStandardReportDataDAOImpl {
	

	private static final long serialVersionUID = 5326464717739558387L;

	protected Query buildQuery(ReportConfiguration config, Session session ) throws ReportDataException {
		
		QueryCriteria reportCriteria = config.getQueryCriteria();
		StandardReportCriteria criteria = (StandardReportCriteria)reportCriteria;
		ReportSetup setup = criteria.getReportSetup();

		ReportParameterSet parameters = setup != null ? setup.getParameterSet() : null;
		if( parameters == null ) {
			throw new ReportDataException("Missing report parameters in report " + config.getReportID() );
		}
		
		Query query = getNamedQuery( session );	
		query.setDate( CommonCriteria.START_DATE, this.getDate( config, true ) );
	    query.setDate( CommonCriteria.END_DATE, this.getDate( config, false ) );
		//Sets facilities
        ReportFacilityDisplayBy facilityDisplayBy = parameters.getFacilityDisplayBy();
        List facilityIds = new ArrayList ();
        if(facilityDisplayBy != null) {
            Set facilities = parameters.getFacilities();            
    		if(facilities != null && !facilities.isEmpty()) {            	
    			for (Iterator i=facilities.iterator(); i.hasNext();){
    				VAFacility facility = ((ReportFacility)i.next()).getFacility();
    				facilityIds.add(facility.getIdentifier());
    			}
            }  
        }   
        ReportFormat format=parameters.getReportFormat();
		if(format!=null && format.getCode().equals(ReportFormat.DETAIL.getCode()))
			setDetailFacilities(parameters, facilityDisplayBy,query,facilityIds);
		//If it is summary and facilityDisplayBy not null.
		else if(facilityDisplayBy!=null)
			setSummaryFacilities(parameters,facilityDisplayBy,query,facilityIds);
		
        Set enrollmentPriorites = parameters.getReportEnrollmentPriorityGroups();
        List priorityIds = new ArrayList ();
        List subPriorityIds = new ArrayList ();
		if(enrollmentPriorites != null && !enrollmentPriorites.isEmpty()) {        	
			for (Iterator i=enrollmentPriorites.iterator(); i.hasNext();){
				ReportEnrollmentPriorityGroup reportPriorityGroup=(ReportEnrollmentPriorityGroup)i.next();
				EnrollmentPriorityGroup group = reportPriorityGroup.getEnrollmentPriorityGroup();
				if(group!=null)
					priorityIds.add(group.getIdentifier());				
				EnrollmentPrioritySubGroup subGroup=reportPriorityGroup.getEnrollmentPrioritySubGroup();
				if(subGroup!=null)
					subPriorityIds.add(subGroup.getIdentifier());
			}
        }       	
		//Set Priority Groups list if provided
		if(!priorityIds.isEmpty()) {
			query.setString(CommonCriteria.ALL_GROUPS, "NO");
        }
		else {
			query.setString(CommonCriteria.ALL_GROUPS, "ALL");				
		}
		//	Set Sub Priority Groups list if provided
		if(!subPriorityIds.isEmpty()) {
			query.setString(CommonCriteria.ALL_SUB_GROUPS, "NO");
        }
		else if(subPriorityIds.isEmpty() && !priorityIds.isEmpty()){
			query.setString(CommonCriteria.ALL_SUB_GROUPS, "NO");
			subPriorityIds.add(new Integer(0));
		}else{
			query.setString(CommonCriteria.ALL_SUB_GROUPS, "ALL");			
			subPriorityIds.add(new Integer(0));
		}
		if(priorityIds.isEmpty())
			priorityIds.add(new Integer(0));
    	query.setParameterList(CommonCriteria.GROUP_PRIORITIES, priorityIds);  
    	query.setParameterList(CommonCriteria.SUB_GROUP_PRIORITIES, subPriorityIds);  
    			
		 Set enrollmentstatuses = parameters.getEnrollmentStatuses();
            List statusIds = new ArrayList ();
    		if(enrollmentstatuses != null && !enrollmentstatuses.isEmpty()) {
            	//set the ids
    			for (Iterator i=enrollmentstatuses.iterator(); i.hasNext();){
    				EnrollmentStatus status = ((ReportEnrollmentStatus)i.next()).getEnrollmentStatus();
    				statusIds.add(status.getIdentifier());
    			}
            }       	
        		//Set enrollment sdtatuses if provided
		if(!statusIds.isEmpty()) {
			query.setString(CommonCriteria.ALL_STATUSES, "NO");
        }
		else {
			query.setString(CommonCriteria.ALL_STATUSES, "ALL");		
			statusIds.add(new Integer(0));
		}
		query.setParameterList(CommonCriteria.ENROLLMENT_STATUSES, statusIds); 	
		
        return query;
	 }
	
	private void setSummaryFacilities(ReportParameterSet parameters,ReportFacilityDisplayBy facilityDisplayBy, Query query, List facilityIds )
	{
		if (ReportFacilityDisplayBy.CODE_VISN.getCode().equals(facilityDisplayBy.getCode()) ||
    			ReportFacilityDisplayBy.CODE_VISN_SITE.getCode().equals(facilityDisplayBy.getCode()) ||
    			ReportFacilityDisplayBy.CODE_SITE.getCode().equals(facilityDisplayBy.getCode()) ||
    			ReportFacilityDisplayBy.CODE_VISN_VAMC.getCode().equals(facilityDisplayBy.getCode()) ||
    			ReportFacilityDisplayBy.CODE_VISN_VAMC_SITE.getCode().equals(facilityDisplayBy.getCode()) ||
    			ReportFacilityDisplayBy.CODE_VAMC.getCode().equals(facilityDisplayBy.getCode())||
				ReportFacilityDisplayBy.CODE_VAMC_SITE.getCode().equals(facilityDisplayBy.getCode()))    	
    	{
			
    		//Set facility ids  if provided
    		if(!facilityIds.isEmpty()) {
    			query.setString(CommonCriteria.ALL_FACILITIES, "NO");
            }
    		else if (ReportFacilityDisplayBy.CODE_VISN.getCode().equals(facilityDisplayBy.getCode())){
    			query.setString(CommonCriteria.ALL_FACILITIES, "NO");
    			facilityIds.add(new Integer(0));
    		}
    		else
    		{ 	
    			query.setString(CommonCriteria.ALL_FACILITIES, "ALL");        			
    			facilityIds.add(new Integer(0));    			
    		}
			query.setParameterList(CommonCriteria.FACILITIES, facilityIds);        		
    	}
		 //NO VISN Option
        if (facilityDisplayBy!=null && ReportFacilityDisplayBy.CODE_VISN.getCode().equals(facilityDisplayBy.getCode()))
        {
            //NOVISN is selected
            if (parameters.isNoVISNPresent()){
                query.setString(CommonCriteria.IS_NO_VISN,CommonCriteria.IS_NO_VISN);
            }
            else {
                query.setString(CommonCriteria.IS_NO_VISN,"VISN");
            }            
        }       
	}
	
	private void setDetailFacilities(ReportParameterSet parameters, ReportFacilityDisplayBy facilityDisplayBy, Query query, List facilityIds )
	{
		List visns=null;
		List facilities=null;
		List vamcs=null;
		if (facilityDisplayBy!=null && ReportFacilityDisplayBy.CODE_VISN.getCode().equals(facilityDisplayBy.getCode()))
		{		
			if(!facilityIds.isEmpty()) {
    			query.setString(CommonCriteria.ALL_FACILITIES, "NO");  
    			visns=facilityIds;
    			facilities=new ArrayList();
    			facilities.add(new Integer(0));
    			vamcs=new ArrayList();
    			vamcs.add(new Integer(0));
            }
    		else {
    			//TODO Check with Venki Set to NO from YES
                query.setString(CommonCriteria.ALL_FACILITIES, "NO");
    			facilities=new ArrayList();  
    			facilities.add(new Integer(0));
    			visns=new ArrayList();  
    			visns.add(new Integer(0));
    			vamcs=new ArrayList();
    			vamcs.add(new Integer(0));
    		}
		}
		else if( facilityDisplayBy!=null && (ReportFacilityDisplayBy.CODE_VISN_SITE.getCode().equals(facilityDisplayBy.getCode()) ||
				ReportFacilityDisplayBy.CODE_SITE.getCode().equals(facilityDisplayBy.getCode())))
				
    	{
			if(!facilityIds.isEmpty()) {
    			query.setString(CommonCriteria.ALL_FACILITIES, "NO");  
    			facilities=facilityIds;
    			visns=new ArrayList();
    			visns.add(new Integer(0));
    			vamcs=new ArrayList();
    			vamcs.add(new Integer(0));
            }
    		else {
    			query.setString(CommonCriteria.ALL_FACILITIES, "ALL");     			
    			facilities=new ArrayList();  
    			facilities.add(new Integer(0));
    			visns=new ArrayList();  
    			visns.add(new Integer(0));
    			vamcs=new ArrayList();
    			vamcs.add(new Integer(0));
    		}	
    	}else if( facilityDisplayBy!=null && (ReportFacilityDisplayBy.CODE_VAMC_SITE.getCode().equals(facilityDisplayBy.getCode())||	
				ReportFacilityDisplayBy.CODE_VAMC.getCode().equals(facilityDisplayBy.getCode())||
				ReportFacilityDisplayBy.CODE_VISN_VAMC_SITE.getCode().equals(facilityDisplayBy.getCode())||				
				ReportFacilityDisplayBy.CODE_VISN_VAMC.getCode().equals(facilityDisplayBy.getCode())))
    	{
    		query.setString(CommonCriteria.ALL_FACILITIES, "NO");  
    		visns=new ArrayList();  
			visns.add(new Integer(0));
			facilities=facilityIds;			
			vamcs=facilityIds;			
    	}
		//If None option selected.
		else{
			query.setString(CommonCriteria.ALL_FACILITIES, "ALL");     			
			facilities=new ArrayList();  
			facilities.add(new Integer(0));
			visns=new ArrayList();  
			visns.add(new Integer(0));
			vamcs=new ArrayList();
			vamcs.add(new Integer(0));
		}
        //NO VISN Option
        if (facilityDisplayBy!=null && ReportFacilityDisplayBy.CODE_VISN.getCode().equals(facilityDisplayBy.getCode()))
        {
            //NOVISN is selected
            if (parameters.isNoVISNPresent()){
                query.setString(CommonCriteria.IS_NO_VISN,CommonCriteria.IS_NO_VISN);
            }
            else {
                query.setString(CommonCriteria.IS_NO_VISN,"VISN");
            }            
        }
        else {
            //set default as always selected for other options
            query.setString(CommonCriteria.IS_NO_VISN,CommonCriteria.IS_NO_VISN);
        }
		query.setParameterList(CommonCriteria.FACILITIES, facilities);
		query.setParameterList(CommonCriteria.VISNS, visns);
		query.setParameterList(CommonCriteria.VAMCS, vamcs);		
	}
}
