package com.fp.bpm.save;

import java.util.ArrayList;
import java.util.List;

import com.fp.common.helper.Constant;
import com.fp.common.logger.APPLogger;
import com.fp.dto.AbstractDataTransport;
import com.fp.dto.Response;
import com.fp.dto.hb.HibernateBean;
import com.fp.dto.save.SaveBean;
import com.fp.dto.save.SaveRequest;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.commondb.exception.CommondbException;

/**
 * Clase que se encarga de persistir en la base de datos los beans.
 * 
 * @author Jorge Vaca
 * @version 2.1
 */
public class Save {

    /**
     * Recorre la lista de orden de envio de beans a la base, Obtiene el savebean y ejecuta el dml.
     * 
     * @param pSaveRequest Objeto con los beans a almacenar en la base de datos.
     * @param pResponse Respuesta del proceso.
     * @return boolean
     * @throws CommondbException
     * @throws Exception
     */
    public boolean process(SaveRequest pSaveRequest, Response pResponse) throws CommondbException, Exception {
        List<String> lOrderPersistentBeans = pSaveRequest.getLOrderPersistentBeans();
        for (String key : lOrderPersistentBeans) {
            Object obj = pSaveRequest.get(key);
            if (obj instanceof SaveBean) {
                APPLogger.getLogger().debug("Request de Mantenimiento recibido: " + pSaveRequest);
                SaveBean sbean = (SaveBean) obj;
                if (sbean.isSave()) {
                    this.saveBean(sbean);
                }
            }
        }
        int size = lOrderPersistentBeans.size();
        for (int i = size; i > 0; i--) {
            Object obj = pSaveRequest.get(lOrderPersistentBeans.get(i - 1));
            if (obj instanceof SaveBean) {
                APPLogger.getLogger().debug("Request de Mantenimiento recibido: " + pSaveRequest);
                SaveBean sbean = (SaveBean) obj;
                this.deleteBean(sbean);
            }
        }

        return true;
    }

    /**
     * Ejecuta sentencias DML contra la base de datos.
     * 
     * @param pSaveBean Referencia a SaveBean
     * @throws CommondbException
     */
    private void saveBean(SaveBean pSaveBean) throws CommondbException, Exception {

        try {
            if (pSaveBean.getModifiedObject() != null) {
                APPLogger.getLogger().debug("Bean para mantenimiento: (saveBean) " + pSaveBean);
                Object expire = ((AbstractDataTransport) pSaveBean.getModifiedObject()).get("expire");
                if (expire != null && Constant.ifYes(expire.toString())) {
                    PersistenceHelper.expire((HibernateBean) pSaveBean.getModifiedObject());
                } else {
                    Object isnew = ((AbstractDataTransport) pSaveBean.getModifiedObject()).get("isnew");
                    if (isnew != null && Constant.ifYes(isnew.toString())) {
                        PersistenceHelper.save((HibernateBean) pSaveBean.getModifiedObject());
                    } else {
                        PersistenceHelper.saveOrUpdate((HibernateBean) pSaveBean.getModifiedObject());
                    }
                }
            }
            for (Object obj : pSaveBean.getModifiedRecords()) {
                APPLogger.getLogger().debug("Bean para mantenimiento de un List: (saveBean) " + pSaveBean);
                Object expire = ((AbstractDataTransport) obj).get("expire");
                if (expire != null && Constant.ifYes(expire.toString())) {
                    PersistenceHelper.expire((HibernateBean) obj);
                } else {
                    Object isnew = ((AbstractDataTransport) obj).get("isnew");
                    if (isnew != null && Constant.ifYes(isnew.toString())) {
                        PersistenceHelper.save((HibernateBean) obj);
                    } else {
                        PersistenceHelper.saveOrUpdate((HibernateBean) obj);
                    }
                }

            }
        } catch (ClassCastException e) {
            return;
            // En este caso no hacer nada si no es un bean persistente.
        }
    }

    /**
     * Ejecuta sentencias DML contra la base de datos.
     * 
     * @param pSaveBean Referencia a SaveBean
     * @throws CommondbException
     */
    public void deleteBean(SaveBean pSaveBean) throws CommondbException, Exception {

        try {
            if (pSaveBean.getDeletedObject() != null) {
                APPLogger.getLogger().debug("Bean para delete: (saveBean) " + pSaveBean);
                PersistenceHelper.delete((HibernateBean) pSaveBean.getDeletedObject());
            }

            for (Object obj : pSaveBean.getDeletedRecords()) {
                APPLogger.getLogger().debug("Bean para delete de un List: (saveBean) " + pSaveBean);
                PersistenceHelper.delete((HibernateBean) obj);
            }
        } catch (ClassCastException e) {
            return;
            // En este caso no hacer nada si no es un bean persistente.
        }
    }

    /**
     * Metodo que elimina los bean que ya se gha realizado commit.
     * 
     * @throws Exception
     */
    public static void cleanSaveBeans(SaveRequest pSaveRequest) throws Exception {
        List<String> lOrderPersistentBeans = pSaveRequest.getLOrderPersistentBeans();
        List<String> ldata = new ArrayList<String>();
        for (String key : lOrderPersistentBeans) {
            ldata.add(key);
        }
        for (String key : ldata) {
            Object obj = pSaveRequest.get(key);
            if (obj instanceof SaveBean) {
                lOrderPersistentBeans.remove(((SaveBean) obj).getBeanAlias());
            }
        }
    }

}
