package ru.yandex.wmtools.common.util.scheduler.timetable;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.common.scheduler.ScheduleType;
import ru.yandex.common.scheduler.timetable.TimetableEntry;
import ru.yandex.common.scheduler.timetable.TimetableEntryDescriptor;
import ru.yandex.common.scheduler.timetable.TimetableService;
import ru.yandex.common.util.functional.Filter;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.InternalProblem;

/**
 * @author avhaliullin
 */
public class TaskRegistrator {
    private static final Logger log = LoggerFactory.getLogger(TaskRegistrator.class);
    private TimetableService timetableService;

    public void setTimetableService(TimetableService timetableService) {
        this.timetableService = timetableService;
    }

    public long scheduleTask(final String beanName, String params, String description, String cronParams, int priority) throws InternalException {
        List<TimetableEntry> entries = timetableService.findScheduledTasks(new Filter<TimetableEntryDescriptor>() {
            @Override
            public boolean fits(TimetableEntryDescriptor timetableEntryDescriptor) {
                return beanName.equals(timetableEntryDescriptor.getTaskName());
            }
        });
        if (entries.isEmpty()) {
            log.debug("No task with name " + beanName + " found, adding new");
            return timetableService.scheduleTask(beanName, params, description, ScheduleType.CRON, cronParams, false, priority);
        } else {
            log.debug("Task " + beanName + " already exists");
            TimetableEntry entry = entries.get(0);
            TimetableEntry newEntry =
                    new TimetableEntry(entry.getTaskId(), beanName, params, description, false, ScheduleType.CRON,
                            cronParams, entry.getLastRunTime(), entry.getLastQueuedTime(), priority);
            if (!entry.equals(newEntry) || !entry.getScheduleParams().equals(cronParams) || entry.getPriority() != priority) {
                log.debug("Old trigger differs from this one");
                if (!timetableService.updateTask(newEntry)) {
                    throw new InternalException(InternalProblem.TMS_INITIALIZATION_PROBLEM, "Failed to update task " + entry.getTaskName());
                }
            }
            return entry.getTaskId();
        }
    }
}
