package com.mns.oms.batch.listener;

import com.mns.oms.batch.domain.JobStatistics;
import com.mns.oms.batch.mapper.CycleAvoidingMappingContext;
import com.mns.oms.batch.mapper.StepDataMapper;
import com.mns.oms.batch.model.JobStepDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

import java.io.File;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Mrinmoy Mandal
 * 
 *         Module: WISMR
 *
 */

@Component
public class JobStatusNotificationListener extends JobExecutionListenerSupport {

	private static final Logger log = LoggerFactory.getLogger(JobStatusNotificationListener.class);
	private JobStatistics jobStats;
	private List<JobStepDetails> stepExecList;
	private List<String> fileList;

	@Autowired
	MongoTemplate mongoTemplate;

	@Override
	public void beforeJob(JobExecution jobExecution) {

		if (jobExecution.getStatus() == BatchStatus.STARTED) {
			log.debug("JobExecution object--> {}", jobExecution);
			log.info("<----------------------------JOB - {} STARTED with job id: {}--------------------------------------->",
					jobExecution.getJobInstance().getJobName(), jobExecution.getJobInstance().getId());
			log.debug("mongoTemplate template---->{}", mongoTemplate);

		}
	}

	@Override
	public void afterJob(JobExecution jobExecution) {
		saveJobStatisticsData(jobExecution);
		if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
			log.info("<----------------------------JOB - {} FINISHED with job id: {}--------------------------------------->",
					jobExecution.getJobInstance().getJobName(), jobExecution.getJobInstance().getId());
		}
	}

	/**
	 * This method will be used to save job statistics data.
	 * 
	 * @param jobExecution
	 */
	private void saveJobStatisticsData(JobExecution jobExecution) {
		jobStats = new JobStatistics();
		stepExecList = new ArrayList<>();
		fileList = new ArrayList<>();
		jobStats.setJobId(jobExecution.getJobInstance().getId());
		jobStats.setJobName(jobExecution.getJobInstance().getJobName());
		jobStats.setStartTime(jobExecution.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
		jobStats.setEndTime(jobExecution.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
		jobStats.setJobStatus(jobExecution.getStatus().toString());
		jobStats.setJobExitStatus(jobExecution.getExitStatus().getExitCode().toString());
		jobStats.setJobExitDescription(jobExecution.getExitStatus().getExitDescription().toString());
		jobStats.setLastModifieDate(
				jobExecution.getLastUpdated().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
		jobStats.setCreatedDate(
				jobExecution.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
		jobExecution.getStepExecutions().forEach(stepExec -> {
			log.debug("Step exec context------> {}", stepExec.getExecutionContext());
			JobStepDetails stepDetails = StepDataMapper.INSTANCE.getStepDetails(stepExec,
					new CycleAvoidingMappingContext());
			stepExecList.add(stepDetails);
			log.debug("File List---> {}", fileList);
			if (stepExec.getExecutionContext().containsKey("fileName")) {
				fileList.add(new File(stepExec.getExecutionContext().getString("fileName")).getName());
			}

		});

		log.debug("JobExecution object--> {}", jobExecution);
		log.debug("JobExecutionstep exec object--> {}", jobExecution.getStepExecutions());
		log.debug("JobExecution job inst object--> {}", jobExecution.getJobInstance());
		log.debug("JobExecution job exec context object--> {}", jobExecution.getExecutionContext());

		jobStats.setFileList(fileList);
		jobStats.setStepDetails(stepExecList);
		log.debug("Job Statistics to be saved in DB-----> {}", jobStats);

		mongoTemplate.save(jobStats);

	}
}this is the issue.....method toInstant in interface java.time.chrono.ChronoLocalDateTime<D> cannot be applied to given types;......explain and fix