package com.fp.viaticos.mail;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults;

import com.fp.common.logger.APPLogger;
import com.fp.dto.save.SaveRequest;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.viaticos.mail.thread.MailPorSolicitud;

/**
 * Clase que se encarga de almacenar comentarios de la tarea y el estatus actual de la solicitud.
 * 
 * @author Jorge Vaca.
 * @version 2.1
 */
public class MailMasivo {

    /**
     * Result que contiene los numeros de solicitud o informes por entregar que ya llegaron a la fecha de vencimeinto y
     * hay que enviar recordatorios.
     */
    protected ScrollableResults rSet;

    /**
     * Recorre el resultset que contiene los numeros de operacion a ejecutar el tareas del lote, ejecuta por operacion.
     * 
     * @param numerohilos Numero de hilos a levantar en paralelo para la ejecucion del lote.
     * @throws Exception
     */
    protected void ejecutar(Integer hilos, SaveRequest pSaverequest) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(hilos);
        try {
            if (rSet != null) {
                while (rSet.next()) {
                    try {
                        Object[] obj = rSet.get();
                        // Ejecuta tareas por operacion o por criterio unico de ejecucion.
                        procesaPorSolicitud(pool, obj, pSaverequest);
                    } catch (Exception e) {
                        APPLogger.getLogger().error(e, e);
                    }
                }
            }
        } finally {
            if (rSet != null) {
                rSet.close();
            }
        }
        // control de finalizacion de ejecucion del bathc.
        pool.shutdown();
        boolean isfinish = pool.isTerminated();
        while (!isfinish) {
            isfinish = pool.isTerminated();
            Thread.sleep(600);
        }
    }

    /**
     * Levanta un hilo por solictud, de la clase que se encarga de enviar notificaciones.
     * 
     * @param pool Objeto que contiene el Ejecutor de hilos.
     * @param obj Objeto que contiene la solicitud tipo y numero de dias desde el cual no tomo una accion en el flujo.
     * @param pSaverequest
     * @throws Exception
     */
    private void procesaPorSolicitud(ExecutorService pool, Object[] obj, SaveRequest pSaverequest) throws Exception {
        MailPorSolicitud thread = new MailPorSolicitud(pSaverequest, (String) obj[0], (String) obj[1], Integer.valueOf(obj[2].toString()));
        pool.execute(thread);
    }

    /** Sentencia que entrega las solicitudes a enviar mail. */
    private static final String JPQL = " select cod_solicitud, cod_tipo, extract(day from(now() - fec_fin_viatico)) + 1 dias "
            + "from via_solicitud where  extract(day from(select now() - fec_fin_viatico))+ 1  between 1 and 4 and cod_estado in ('SAP','IPI') ant tipo = 'SOL' ";

    /**
     * Metodo que obtiene las solicitudes a enviar mail masivos.
     * 
     * @throws Exception
     */
    protected void fillRset() throws Exception {
        SQLQuery qry = PersistenceHelper.getSession().createSQLQuery(MailMasivo.JPQL);
        rSet = qry.scroll();
    }

}
