/**
 * 
 */
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.ReportNameResolver;
import gov.va.med.fw.report.data.QueryCriteria;
import gov.va.med.fw.report.data.ReportDataException;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.lookup.CancelDeclineReason;
import gov.va.med.esr.common.model.lookup.ReportFacilityDisplayBy;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.report.ReportCancelDeclineReason;
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   KATIKM
 *
 */
public class CancelDeclineReportDataDAOImpl extends AbstractStandardReportDataDAOImpl {

	private static final long serialVersionUID = -4747089852162276203L;
    
    protected Query buildQuery(ReportConfiguration config, Session session) throws ReportDataException {

		//Get the query with default from and to date parameters
		Query query = null;
		if (getNameResolver() != null) {
			query = this.getNamedQuery(getNameResolver().getReportName(config),session);
		}
		else {
			query = this.getNamedQuery(session);
		}
	
		//Set in the base class	
		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.setDate(CommonCriteria.START_DATE, parameters.getFromDate());
		query.setDate(CommonCriteria.END_DATE, parameters.getToDate());
		
		//Cancel Decline status selections
		Set cdReasons = parameters.getCancelDeclineReasons();
		query.setParameterList("cdReasonType", getCDReasonIds(cdReasons));
		
	    ReportFacilityDisplayBy facilityDisplayBy = parameters.getFacilityDisplayBy();
	    if(facilityDisplayBy != null && StringUtils.isNotEmpty(facilityDisplayBy.getCode())) {
	        if(StringUtils.equals(facilityDisplayBy.getCode(),ReportFacilityDisplayBy.CODE_VISN.getCode())) {
	            List visns = this.getFacilitityIds(parameters.getFacilities());
	            if(visns != null && !visns.isEmpty()) {
	                query.setParameterList( "facilityList", visns.toArray() );
	            }
                //case where novisn is selected
                else {
                    List facilities = new ArrayList();
                    facilities.add(new Integer(0));
                    query.setParameterList( "facilityList", facilities);
                }
                //NOVISN is selected
                if (parameters.isNoVISNPresent()){
                    query.setString(CommonCriteria.IS_NO_VISN,CommonCriteria.IS_NO_VISN);
                }
                else {
                    query.setString(CommonCriteria.IS_NO_VISN,"VISN");
                }                
	        //When 0, more or all facilities selected	            
	        }
	        else {
	            Set reportFacilities = parameters.getFacilities();
	            if(reportFacilities == null || reportFacilities.isEmpty()) {
	                List facilities = new ArrayList();
	                facilities.add(new Integer(0));
	                query.setParameterList( "facilityList", facilities);
	                query.setString("ALL","ALL");
	            } else {
	                query.setParameterList( "facilityList", this.getFacilitityIds(reportFacilities));
	                query.setString("ALL","NO");
	            }
	        }     	        	        
	    }
		return query;
	}

	private List getCDReasonIds(Set cdReasons) {
	    Iterator i = cdReasons != null ? cdReasons.iterator() : null;
	    ArrayList list = new ArrayList();
	    while( i != null && i.hasNext() ) {
	        ReportCancelDeclineReason cdReason = (ReportCancelDeclineReason)i.next();
	        if(cdReason != null) 
	        	list.add(((CancelDeclineReason)cdReason.getLookup()).getIdentifier());
	    }
	    return list;
	}
	private List getFacilitityIds(Set facilities) {
	    Iterator i = facilities != null ? facilities.iterator() : null;
	    ArrayList list = new ArrayList();
	    while( i != null && i.hasNext() ) {
	        ReportFacility rFacility = (ReportFacility)i.next();
	        if(rFacility != null) list.add(((VAFacility)rFacility.getLookup()).getIdentifier());
	    }
	    return list;
	}
}
