package eu.dnetlib.data.emailSender;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.Calendar;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * Created by kiatrop on 10/5/2017.
 */


public class EmailScheduler implements ServletContextListener {

    private int delay = 0;
    private final Logger logger = Logger.getLogger(EmailScheduler.class);

    @Autowired
    private String beautySleep;

    @Autowired
    private String targetHour;
    @Autowired
    private String targetMinute;
    @Autowired
    private String targetSecond;
    @Autowired
    private EmailSender emailSender;

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        WebApplicationContextUtils
                .getRequiredWebApplicationContext(servletContextEvent.getServletContext())
                .getAutowireCapableBeanFactory()
                .autowireBean(this);

        logger.debug("Initializing EmailScheduler with beautySleep " + beautySleep + " and begin time " + targetHour+":"+targetMinute+":"+targetSecond + " and email sender " + emailSender);
        delay = getInitialDelaySeconds(Integer.parseInt(targetHour), Integer.parseInt(targetMinute), Integer.parseInt(targetSecond));
        logger.debug("EmailScheduler will wait "+delay + " seconds");
        
        final ScheduledFuture<?> resetHandle = scheduler.scheduleAtFixedRate(emailSender, delay, Integer.parseInt(beautySleep), SECONDS);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        logger.info("Shutting down EmailScheduler.");
        scheduler.shutdown();
    }

    private int getInitialDelaySeconds(int targetHour, int targetMinute, int targetSecond) {
        int delay = 0;  // delay in seconds

        // calculate second of target run time within a day
        int target = targetHour*60*60+targetMinute*60+targetSecond;

        // calculate second of current time within a day
        Calendar calendar = Calendar.getInstance();
        int second = calendar.get(Calendar.SECOND);
        int minute = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int current = hour*60*60+minute*60+second;

        if(target > current) {
            delay = target - current;
        } else {
            // one day has 86400 seconds
            delay = 86400 - (current - target);
        }

        return delay;
    }

    public void setEmailSender(EmailSender emailSender) {
        this.emailSender = emailSender;
    }

    public void setBeautySleep(String beautySleep) {
        this.beautySleep = beautySleep;
    }

    public String getBeautySleep() {
        return beautySleep;
    }

    public EmailSender getEmailSender() {
        return emailSender;
    }

    public String getTargetHour() {
        return targetHour;
    }

    public void setTargetHour(String targetHour) {
        this.targetHour = targetHour;
    }

    public String getTargetMinute() {
        return targetMinute;
    }

    public void setTargetMinute(String targetMinute) {
        this.targetMinute = targetMinute;
    }

    public String getTargetSecond() {
        return targetSecond;
    }

    public void setTargetSecond(String targetSecond) {
        this.targetSecond = targetSecond;
    }
}
