package com.capgemini.reports.quartz.jobs;

import com.capgemini.reports.database.DataBaseReportHelper;
import com.capgemini.reports.exceptions.NotFoundException;
import com.capgemini.reports.execution.AbstractExecutionReport;
import com.capgemini.reports.execution.posting.DelayedPostingStategy;
import com.capgemini.reports.queuing.EmbeddedServer;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

import javax.jms.JMSException;
import javax.naming.NamingException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/** This Quartz {@link Job} posts a report into the queue for execution. */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
// Required for Quartz
@NoArgsConstructor
public class DelayedJob implements Job, Serializable {

    private static final long serialVersionUID = -4459018522846677264L;

    /**
     * Executes the requested job. The job is a report execution. <br>
     * This method is triggered automatically by Quartz when the time comes.<br>
     * An {@link AbstractExecutionReport} instance is obtained, and sent to the HornetQ queue through the {@link EmbeddedServer}.
     * 
     * @param jobExecutionContext a {@link JobExecutionContext} containing a {@link JobDataMap} that explains what report to execute.
     */
    @Override
    public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // Initialize variable
        JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();

        // Retrieve the Report
        AbstractExecutionReport<?, ?> report = (AbstractExecutionReport<?, ?>) dataMap.get(DelayedPostingStategy.JOB_DETAIL_KEY_REPORT);

        // Log the start
        Date startDate = Calendar.getInstance().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        log.info("Execution of the scheduled job for the report {} at {}.", report.getReportIdentifier().getReportName(), sdf.format(startDate));

        // Put the report in the queues
        try {
            EmbeddedServer.produce(report);
        } catch (JMSException | NamingException e) {
            String msg = "Unable to send the report in the queues.";
            log.error(msg, e);
            throw new JobExecutionException(e);
        }

        // Save progress in database
        try {
            DataBaseReportHelper.updateDelayedLaunch(report.getReportTechnicalUid());
        } catch (NotFoundException e) {
            log.warn("Unable to update launch satus of delayed report, UID = " + report.getReportTechnicalUid(), e);
        }
    }
}
