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

import gov.va.med.esr.common.model.person.ApplicationInProcess;
import gov.va.med.esr.common.model.person.EnrollmentApplication;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.persistent.person.ApplicationInProcessDAO;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.persistent.hibernate.GenericDAOImpl;

import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;
import org.hibernate.lob.SerializableClob;

import com.thoughtworks.xstream.XStream;

public class ApplicationInProcessDAOImpl  extends GenericDAOImpl implements ApplicationInProcessDAO {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8030055516741362319L;
	
	public static final String APPLICATION_SSN_QUERY = "ApplicationInProcess_GetBySsn";
	public static final String INPROCESS_PERSON_ICN_QUERY = "InProcess_Person_GetByIcn";
	public static final String COMPLETE_PERSON_ICN_QUERY = "Complete_Person_GetByIcn";
	public static final String APPLICATION_ICN_QUERY = "ApplicationInProcess_GetByIcn";
    public static final String GET_AIP_BY_EAID = "ApplicationInProcess_GetAIPByEAID";
	public static final String PARAM_SSN = "ssn";	
	public static final String PARAM_ICN = "icn";
	public static final String PARAM_EAID = "eaid";


	
	/*public List getBySsn(String ssn) throws DAOException {
		ArrayList personList = new ArrayList();
		try
        {
			
			List results = findByNamedQueryAndNamedParam(APPLICATION_SSN_QUERY, PARAM_SSN, ssn.replaceAll("-", ""));
            
			if ((results == null) || (results.isEmpty())) {
				return personList;
			}
			for (int i=0; i<results.size(); i++) {
				SerializableClob clob = (SerializableClob)results.get(0);

				Person p = deserializeXML(clob);  
				personList.add(p);
			}
       }
        catch(Exception e)
        {
        	logger.error("Error in ApplicationInProcessDAOImpl.getBySsn retrieving where ssn=" + ssn +"\n"+e.toString());
        	throw new DAOException(e.toString());
        } 
        return personList;
    }*/

	public ApplicationInProcess getByIcn(String icn) throws DAOException {
		Validate.notNull(icn, "ICN cannot be null");
		
		try
        {
			List results = findByNamedQueryAndNamedParam(APPLICATION_ICN_QUERY, PARAM_ICN, icn);
		    verifyDataIntegrity(icn, results);

		    return results.size()==0? null : (ApplicationInProcess)results.get(0);
		}
        catch(Exception e)
        {
            throw new DAOException("getByIcn failed for icn: " + icn, e);
        } 
 	}
	
	public Person getInProcessPersonByIcn(String icn) throws DAOException {
		Validate.notNull(icn, "ICN cannot be null");

		Person p = null;
		try
        {
			List results = findByNamedQueryAndNamedParam(INPROCESS_PERSON_ICN_QUERY, PARAM_ICN, icn);
		    verifyDataIntegrity(icn, results);
          
		    if (results.size() > 0) {
				SerializableClob clob = (SerializableClob)results.get(0);	
				p = deserializeXML(clob);
			}
       }
        catch(Exception e)
        {
            throw new DAOException("getInProcessPersonByIcn failed for icn: " + icn, e);
        } 
 		return p;
    }

	
	
    public Person getCompletedPersonByIcn(String icn) throws DAOException {
    	Validate.notNull(icn, "ICN cannot be null");

		Person p = null;
		try
        {
			List results = findByNamedQueryAndNamedParam(COMPLETE_PERSON_ICN_QUERY, PARAM_ICN, icn);
		    verifyDataIntegrity(icn, results);
          
		    if (results.size() > 0) {
				SerializableClob clob = (SerializableClob)results.get(0);	
				p = deserializeXML(clob);
			}
       }
        catch(Exception e)
        {
            throw new DAOException("getInProcessPersonByIcn failed for icn: " + icn, e);
        } 
 		return p;
	}

	private void verifyDataIntegrity(String icn, List results) throws DAOException {
        if (results.size() > 1) {
     		throw new DAOException("Found more than one record in AplicationInProcess for ICN(VPID): " + icn);
        }
    }
    
	public Person deserializeXML(SerializableClob clob) {

		Person p = null;

		XStream xstream = new XStream();  
		InputStream istream = null;
		try {
			istream = clob.getAsciiStream();
			p = (Person)xstream.fromXML(istream);
		} catch (SQLException e) {
	       	logger.error("Error in ApplicationInProcessDAOImpl.deserializeXML "+"\n"+e.toString());
		} finally {
			if (istream != null) {
				IOUtils.closeQuietly(istream);
			}
		}
		return p;
	}   	
	
}
