package gov.va.med.esr.common.persistent.messaging.hibernate;

// Java Classes
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;

import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.persistent.hibernate.GenericDAOImpl;

import gov.va.med.esr.common.model.messaging.IrsTransmissionLogDetailEntry;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.persistent.messaging.IrsTransmissionLogDetailEntryDAO;


/**
 * Provides methods to retrieve a message log entry entity
 *
 * Project: Common</br>
 * Created 9/28/2015 </br>
 *
 * @author DNS   faulkj
 */
public class IrsTransmissionLogDetailEntryDAOImpl extends GenericDAOImpl implements IrsTransmissionLogDetailEntryDAO {
	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = -4381743890112053737L;

	@Transactional
    public IrsTransmissionLogDetailEntry getById(BigDecimal identifier) throws DAOException {
        try {
            HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQueryAndNamedParam( FIND_BY_IDENTIFIER,PARAM_IDENTIFIER,identifier );

            // Should only return one value
            return results.isEmpty() ? null : (IrsTransmissionLogDetailEntry) results.get(0);
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to get the message log entry by identifier", e);
        }
    }

    @Transactional
    public List<IrsTransmissionLogDetailEntry> findByPersonId(EntityKey personId) throws DAOException {
    	try {
            HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQueryAndNamedParam(FIND_BY_PERSON_ID,
                    PARAM_PERSON_ID, (BigDecimal) personId.getKeyValue());

            return results;
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to get the message log entry by identifier", e);
        }
    }
    @Transactional
    public IrsTransmissionLogDetailEntry findMostRecentEntry(PersonEntityKey personId, String taxYear) throws DAOException {
    	try {
            String [] params = {PARAM_PERSON_ID,PARAM_TAX_YEAR};
            Object [] values = {personId.getKeyValue(),taxYear};

    		HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQueryAndNamedParam(FIND_MOST_RECENT,
                    params, values);

            // Should only return one value
            return results.isEmpty() ? null : (IrsTransmissionLogDetailEntry) results.get(0);
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to get the most recent tax year entry", e);
        }
    }

    public List<IrsTransmissionLogDetailEntry> findAllowedCorrectionYears(EntityKey personId) throws DAOException {
    	try {
            HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQueryAndNamedParam(FIND_CORRECTION_YEARS,
                    PARAM_PERSON_ID, (BigDecimal) personId.getKeyValue());

            return results;
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to get allowed correction years", e);
        }
    }
    @Transactional
    public List<IrsTransmissionLogDetailEntry> getFailedPersonTransmissions() throws DAOException {
    	try {
            HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQuery(FIND_FAILURES);

            return results;
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to find person transmit failures", e);
        }
    }

    public IrsTransmissionLogDetailEntry findOriginalForYear(String ien, String taxYear) throws DAOException {
    	try {
            String [] params = {PARAM_IEN,PARAM_TAX_YEAR};
            Object [] values = {ien,taxYear};

    		HibernateTemplate tpl = this.getHibernateTemplate();
            List results = tpl.findByNamedQueryAndNamedParam(FIND_ORIGINAL_FOR_YEAR,
                    params, values);

            if (results != null) {
	            Comparator comparator = new Comparator() {
	                public int compare(Object pObject1, Object pObject2) {
	                    Date date1 = (pObject1 instanceof IrsTransmissionLogDetailEntry) ? ((IrsTransmissionLogDetailEntry)pObject1).getCreatedOn() : null;
	                    Date date2 = (pObject2 instanceof IrsTransmissionLogDetailEntry) ? ((IrsTransmissionLogDetailEntry)pObject2).getCreatedOn() : null;
	                    return (date1 != null && date2 != null) ? (-date1.compareTo(date2)) : 0;
	                }
	            };


	            Collections.sort(results, comparator);
	            Collections.reverse(results);
            }


            return results.isEmpty() ? null : (IrsTransmissionLogDetailEntry) results.get(0);
        }
        catch (DataAccessException e) {
            throw new DAOException("Failed to get the most recent entry by IEN", e);
        }
    }



}