import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.joda.time.DateTime;
import org.springframework.orm.hibernate3.HibernateCallback;

public abstract class MetOfficeDao<T> extends GenericDao<T, Long> implements MetOfficeDaoInterface<T>{


  /**
   * Calls a stored procedure returning a ResultSet that is 
   * concerted to a List<T> using org.apache.commons.dbutils.ResultSetHandler as a basic ORM
   */
  @Override
  public List<T> getMetOfficeObservations(final String aGSP, 
              final DateTime aStartForecastDate, final DateTime aEndForecastDate, final DateTime aRequestDate, final Class<T> aType) {
    return getHibernateTemplate().execute(new HibernateCallback<List<T>>()
    {
      List<T> result = new ArrayList<T>();
      public List<T> doInHibernate(Session aSession) {
        //The connection is not directly available using hibernate unl;ess you use a deprecated method
        getSession().doWork(new Work() {
                 @Override
                 public void execute(Connection conn) throws SQLException {
                   
                   // set up call to storedProcedure
                   PreparedStatement ps = conn.prepareStatement("exec procGetObservationsForGSPAndDates ?,? ");
                               
                   ps.setEscapeProcessing(true);
                   ps.setQueryTimeout(500);

                   int i = 1; //jdbc params start at 1
                   ps.setString(i++, aGSP); 
                   ps.setDate(i++, new java.sql.Date(aStartForecastDate.toDate().getTime()));
                   
                   ResultSetHandler<List<T>> resultSetHandler = new BeanListHandler<T>(aType);
                   
                   if(ps.execute())    //returns true when the procedure is done
                   {
                     ResultSet rs = ps.getResultSet();
                     //convert the ResultSet to a List<T> using the ResultSetHandler
                     List<T> results = (List<T>) resultSetHandler.handle(rs);
                     result = results;
                   }
                 }
             });
        return result;
      }
    });
  }
}