/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.controller.catalog;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Holiday;
import com.arrebol.taxiservicios.model.core.User;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author oscarvargas
 */
public class HolidayController extends ConnectionManager implements Serializable {

    /**
     *
     * Searching all holidays.
     *
     * @return List of holidays
     */
    public List<Holiday> fillHolidayDatatable() {
        logger.info("fillHolidayDatatable");

        List<Holiday> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<Holiday> criteria = builder.createQuery(Holiday.class);
            Root<Holiday> root = criteria.from(Holiday.class);

            Path<String> idPath = root.get("id");
            Path<Date> holiday = root.get("holiday");
            Path<String> description = root.get("description");

            criteria.select(
                    builder.construct(Holiday.class, idPath, holiday, description
                    ));
            
            criteria.orderBy(builder.asc(root.get("holiday")));

            result = session.createQuery(criteria).getResultList();

            logger.info("Total of holidays found : " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load list of holidays", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillHolidayDatatable", e);
            rollback(transaction);
        }

        return result;
    }

    /**
     *
     * @param holiday
     * @param userId
     * @return
     */
    public boolean saveHoliday(Holiday holiday, String userId) {
        logger.info("saveHoliday");

        boolean success = false;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            if (holiday.getId() != null) {
                CriteriaUpdate<Holiday> update = builder.createCriteriaUpdate(Holiday.class);
                Root<Holiday> root = update.from(Holiday.class);

                update.set("holiday", holiday.getHoliday());
                update.set("description", holiday.getDescription());
                update.set("lastUpdatedBy", new User(userId, ""));
                update.set("lastUpdatedOn", new Date());

                update.where(builder.equal(root.get("id"), holiday.getId()));

                session.createQuery(update).executeUpdate();
                logger.info("Holiday was edited - " + holiday);
            } else {

                holiday.setId(UUID.randomUUID().toString());
                holiday.setCreatedBy(new User(userId, ""));
                holiday.setCreatedOn(new Date());

                session.save(holiday);
                logger.info("Holiday was saved - " + holiday);
            }

            transaction.commit();
            success = true;
        } catch (HibernateException e) {
            logger.error("The holiday can not be saved - " + holiday, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveHoliday(" + holiday + ")", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     * 
     * @param holiday
     * @return 
     */
    public boolean deleteHoliday(Holiday holiday) {
        logger.info("deleteHoliday");

        boolean success = false;
        Transaction transaction = null;
        try {
            if (holiday.getId() != null) {
                Session session = HibernateUtil.getSessionFactory().getCurrentSession();
                transaction = session.beginTransaction();
                CriteriaBuilder builder = session.getCriteriaBuilder();

                CriteriaDelete<Holiday> delete = builder.createCriteriaDelete(Holiday.class);
                Root<Holiday> root = delete.from(Holiday.class);

                delete.where(builder.equal(root.get("id"), holiday.getId()));

                session.createQuery(delete).executeUpdate();
                transaction.commit();
                
                logger.info("Holiday was deleted - " + holiday.getId());

                success = true;
            }
        } catch (HibernateException e) {
            logger.error("The holiday can not be deleted - " + holiday, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method  deleteHoliday(" + holiday + ")", e);
            rollback(transaction);
        }
        return success;
    }

    private static final long serialVersionUID = 7348729555190223915L;

    final Logger logger = LogManager.getLogger(HolidayController.class);

    public HolidayController() {
    }

}
