

package gov.va.med.cds.ars.persistence;


import gov.va.med.cds.ars.requestresponse.generated.HTReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.HTResponseType;
import gov.va.med.cds.ars.requestresponse.generated.LocationReportDataType;
import gov.va.med.cds.exception.PersistenceException;

import java.sql.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.hibernate.HibernateException;
import org.hibernate.Query;


public abstract class AbstractReadableReportsPersistenceManager extends AbstractHibernatePersistenceManager
    implements ReadableReportsPersistenceManagerInterface {
	
    protected HTResponseType responseType = new HTResponseType();
    // Earliest Census start date 09/10/2005 
    public static final GregorianCalendar CENSUS_EARLIEST_START_DATE = new GregorianCalendar(2005, 8, 10);
    public static final long MILLIS_IN_ONE_DAY = 24*60*60*1000;

    public abstract HTResponseType performReadReportAggregate( HTReportFilterType aReportFilter ) throws PersistenceException;
    
    
    protected Integer getSurveyCount( List<? extends LocationReportDataType> results )
    {
        Integer count = null;
        
        if ( results != null )
        {
            count = 0;
            
            for ( LocationReportDataType locationReportData : results )
            {
                count += locationReportData.getRecordCount();
            }
        }  
        
        return count;
    }

    
    protected XMLGregorianCalendar dateToXMLGregorianCalendar( int year, int month, int day ) 
    {
        XMLGregorianCalendar newXMLGregorianCalendar = null;
        DatatypeFactory datatypeFactory;
        try
        {
            datatypeFactory = DatatypeFactory.newInstance();
            newXMLGregorianCalendar = datatypeFactory.newXMLGregorianCalendarDate( year, month, day, 0 );
        }
        catch ( DatatypeConfigurationException e )
        {
            // eat exception
            e.printStackTrace();
        }
        
        return newXMLGregorianCalendar;
    }
    
    
    protected XMLGregorianCalendar gregorianCalendarToXMLGregorianCalendar( GregorianCalendar aDateTime ) 
    {
        XMLGregorianCalendar newXMLGregorianCalendar = null;
        DatatypeFactory datatypeFactory;
        try
        {
            datatypeFactory = DatatypeFactory.newInstance();
            newXMLGregorianCalendar = datatypeFactory.newXMLGregorianCalendar( aDateTime );
        }
        catch ( DatatypeConfigurationException e )
        {
            // eat exception
            e.printStackTrace();
        }
        
        return newXMLGregorianCalendar;
    }
    
    
    protected Date formatDate( XMLGregorianCalendar aDate )
    {
        Date sqlDate = null;
        if ( aDate != null )
        {
            GregorianCalendar convertDate = aDate.toGregorianCalendar();
            java.util.Date utilDate = convertDate.getTime();
            
            sqlDate = new Date( utilDate.getTime() );
        }

        return sqlDate;
    }


    @SuppressWarnings( "rawtypes" )
    protected List queryForReportData( Query aQuery )
    {
        List results = null;
        
        try
        {
            results = aQuery.list();
            if ( LOGGER.isDebugEnabled() )
            {
                LOGGER.debug( "Result size: " + results.size() );
//                for ( Object object : results )
//                {
//                    LOGGER.debug( object.getClass().getName() + " *** " + object );
//                }
            }

        }
        catch ( HibernateException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw e;
        }
        
        return results;
    }
    /*
    protected void validateStartDateAndEndDate(XMLGregorianCalendar xmlStartDate, XMLGregorianCalendar xmlEndDate) throws ValidationException{
		
    	GregorianCalendar startDate = xmlStartDate.toGregorianCalendar();
		if( Calendar.SUNDAY != startDate.get(Calendar.DAY_OF_WEEK) ){
			// start date is not Sunday
			throw new ValidationException(ErrorCodeEnum.CENSUS_REPORT_INVALID_START_DATE, xmlStartDate.toString());	
		}
		if ( startDate.getTimeInMillis() < CENSUS_EARLIEST_START_DATE.getTimeInMillis()){
			// start date precedes 09/10/2005
			throw new ValidationException(ErrorCodeEnum.CENSUS_REPORT_INVALID_START_DATE, xmlStartDate.toString());	
		}
		
		GregorianCalendar endDate = xmlEndDate.toGregorianCalendar();
		
		if( Calendar.SATURDAY != endDate.get(Calendar.DAY_OF_WEEK) ){
			// end date is not Saturday;
			throw new ValidationException(ErrorCodeEnum.CENSUS_REPORT_INVALID_END_DATE , xmlEndDate.toString());
		}
		
		if( 6 != ((endDate.getTimeInMillis()-startDate.getTimeInMillis())/MILLIS_IN_ONE_DAY ) ){
			// end day is not the following Saturday of start date
			throw new ValidationException(ErrorCodeEnum.CENSUS_REPORT_INVALID_TIME_PERIOD, xmlEndDate.toString(), xmlStartDate.toString());
		}
		
		GregorianCalendar now = new GregorianCalendar();
		now.setTimeInMillis(now.getTimeInMillis()-MILLIS_IN_ONE_DAY);	// substract 1 day
		
		if( endDate.getTimeInMillis() > now.getTimeInMillis()){
			// end date exceeds current date
			throw new ValidationException(ErrorCodeEnum.CENSUS_REPORT_INVALID_END_DATE, xmlEndDate.toString());
		}
		
		return;
    }
*/
}

