package ch.zhaw.gartenverwaltung.backgroundtasks;

import ch.zhaw.gartenverwaltung.CropDetailController;
import ch.zhaw.gartenverwaltung.backgroundtasks.weather.WeatherGradenTaskPlanner;
import ch.zhaw.gartenverwaltung.io.CropList;
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
import ch.zhaw.gartenverwaltung.io.PlantList;
import ch.zhaw.gartenverwaltung.io.TaskList;
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
import ch.zhaw.gartenverwaltung.types.Task;

import javax.mail.MessagingException;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Class with tasks which must be executed periodic and not triggered by user. Method run must be called in a fix interval.
 */
public class BackgroundTasks extends TimerTask {
    private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName());
    private final TaskList taskList;
    private final Notifier notifier;
    private final WeatherGradenTaskPlanner weatherGardenTaskPlaner;

    public BackgroundTasks(TaskList taskList, CropList cropList, PlantList plantList) {
        this.taskList = taskList;
        notifier = new Notifier(taskList, plantList, cropList);
        weatherGardenTaskPlaner = new WeatherGradenTaskPlanner(taskList, plantList, cropList);
    }

    /**
     * Changes the field "nextExecution" of all tasks if it's in the past to the actual date as long as they are not done.
     * @throws IOException if the taskList can't be read.
     */
    private void movePastTasks() throws IOException {
        List<Task> taskList = this.taskList.getTaskList(LocalDate.MIN.plusDays(1), LocalDate.now().minusDays(1));
        for (Task task : taskList) {
            if (!task.isDone()) {
                task.setNextExecution(LocalDate.now());
                this.taskList.saveTask(task);
            }
        }
    }

    /**
     * Method to call if Tasks should be executed. It calls all Background tasks after each other.
     */
    @Override
    public void run() {
        try {
            movePastTasks();
        } catch (IOException e) {
            e.printStackTrace();
            LOG.log(Level.WARNING, "Could not execute Background Task: move past Tasks ", e.getCause());
        }
        try {
            weatherGardenTaskPlaner.refreshTasks();
        } catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
            e.printStackTrace();
            LOG.log(Level.WARNING, "Could not execute Background Task: Refresh Tasks by WeatherGardenTaskPlaner ", e.getCause());
        }
        try {
            notifier.sendNotifications();
        } catch (IOException | MessagingException | HardinessZoneNotSetException e) {
            e.printStackTrace();
            LOG.log(Level.WARNING, "Could not execute Background Task: send Notification for due Tasks", e.getCause());
        }
    }
}

