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

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

import org.apache.commons.lang.Validate;
import org.hibernate.Query;
import org.hibernate.Session;

import gov.va.med.fw.model.lookup.AbstractLookup;
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.report.data.hibernate.HibernateReportDataDAO;

import gov.va.med.esr.common.model.report.ReportLookupParameter;
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;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.PSDelegateService;

/**
 * Project: Common</br>
 * Class: AbstractStandardReportDataDAOImpl</br>
 * Created on: Apr 12, 2006</br>
 *
 * @author DNS   LEV
 *
 */
public abstract class AbstractStandardReportDataDAOImpl extends HibernateReportDataDAO {

   /**
    * A serialization key
    */
   private static final long serialVersionUID = 1178123948624532738L;
   
   /**
    * An instance of psDelegateService
    */
   protected PSDelegateService psDelegateService = null;
   
   /**
    * An instance of lookupService
    */
   protected LookupService lookupService = null;
   
   /**
    * An instance of name resolver
    */
   protected ReportNameResolver nameResolver = null;
   
   /**
    * A default constructor
    */
   protected AbstractStandardReportDataDAOImpl() {
      super();
   }

   /**
    * @param psDelegateService The psDelegateService to set.
    */
   public void setPsDelegateService(PSDelegateService psDelegateService) {
      this.psDelegateService = psDelegateService;
   }

   /**
    * @param lookupService The lookupService to set.
    */
   public void setLookupService(LookupService lookupService) {
      this.lookupService = lookupService;
   }
   
	/**
	 * @return Returns the nameResolver.
	 */
	public ReportNameResolver getNameResolver() {
		return this.nameResolver;
	}
	
	/**
	 * @param nameResolver The nameResolver to set.
	 */
	public void setNameResolver(ReportNameResolver nameResolver) {
		this.nameResolver = nameResolver;
	}

/**
    * @see gov.va.med.fw.report.data.ReportDataDAO#preDataRetrieval(gov.va.med.fw.report.ReportConfiguration)
    */
   public void preDataRetrieval( ReportConfiguration config ) throws ReportDataException {
      
      QueryCriteria reportCriteria = config.getQueryCriteria();

      if( reportCriteria instanceof StandardReportCriteria ) {
         StandardReportCriteria criteria = (StandardReportCriteria)reportCriteria;
         ReportSetup setup = criteria.getReportSetup();
         ReportParameterSet parameters = setup.getParameterSet();
         
         criteria.setStartDate( this.getDate( config, true ) );
         criteria.setEndDate( this.getDate( config, false ) );
         
         if (parameters.getFileType() != null) {
        	 criteria.setFileType(parameters.getFileType().getCode());
         }
      }
   }
   
   /**
    * @see gov.va.med.fw.report.data.hibernate.ConfigurableReportDataDAO#initDao()
    */
   protected void initDao() throws Exception {
      super.initDao();
      Validate.notNull( this.psDelegateService, "A PS delegate service must be configured" );
      Validate.notNull( this.lookupService, "A lookup service must be configured" );
   }
   
   protected Date getDate( ReportConfiguration config, boolean isStartDate ) {
      
      Date date = null;
      QueryCriteria reportCriteria = config.getQueryCriteria();
      if( reportCriteria instanceof StandardReportCriteria ) {
         
         // Get a criteria
         StandardReportCriteria criteria = (StandardReportCriteria)reportCriteria;
         ReportSetup setup = criteria.getReportSetup();
         
         // Get a parameter set to get start/end date
         ReportParameterSet parameters = setup.getParameterSet();
         date = isStartDate ? parameters.getFromDate() : parameters.getToDate();
         
      }
      return date;
   }
      
   /**
    * @see gov.va.med.esr.common.report.data.MSTReportDataDAO#buildMSTStatusCriteria(gov.va.med.fw.report.ReportConfiguration)
    */
   protected Query buildQuery( ReportConfiguration config, Session session ) throws ReportDataException {
   
      Query query = this.getNamedQuery( session );
      query.setDate( CommonCriteria.START_DATE, this.getDate( config, true ) );
      query.setDate( CommonCriteria.END_DATE, this.getDate( config, false ) );
      return query;
   }
   
   protected List getLookupIds(Set reportLookupParameterSet){
	    Iterator i = reportLookupParameterSet != null ? reportLookupParameterSet.iterator() : null;
	    ArrayList list = new ArrayList();
	    while( i != null && i.hasNext() ) {
	    	ReportLookupParameter reportLookupParameter = (ReportLookupParameter)i.next();
	        if(reportLookupParameter != null) 
	        	list.add(((AbstractLookup)reportLookupParameter.getLookup()).getIdentifier());
	    }
	    return list;
   }
   
   protected List getLookupIds(Class lookupClass) throws ReportDataException {
       try {
           List lookupList = lookupService.findAll(lookupClass);
            Iterator i = lookupList != null ? lookupList.iterator() : null;
            ArrayList list = new ArrayList();
            while( i != null && i.hasNext() ) {
                AbstractLookup lookup = (AbstractLookup)i.next();
                    list.add(lookup.getIdentifier());
            }
            return list;
       }catch(Exception e){
           throw new ReportDataException(e.getMessage(),e);
       }
   }      
}