package com.collective.celos;

import java.text.ParseException;
import java.util.Date;
import java.util.SortedSet;
import java.util.TreeSet;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.quartz.CronExpression;

import com.fasterxml.jackson.databind.node.ObjectNode;

public class CronSchedule implements Schedule {

    public final static String CONFIG_PROP = "celos.cron.config";
    
    private CronExpression cronExpression;

    public CronSchedule(ObjectNode properties) {
        String cronConfig = Util.getStringProperty(properties, CONFIG_PROP);
        try {
            CronExpression.validateExpression(cronConfig);
            cronExpression = new CronExpression(cronConfig);
            cronExpression.setTimeZone(DateTimeZone.UTC.toTimeZone());
        } catch (ParseException e) {
            throw new IllegalArgumentException("Error in cron expression", e);
        }
    }

    public String getCronExpression() {
        return cronExpression.getCronExpression();
    }

    @Override
    public SortedSet<ScheduledTime> getScheduledTimes(ScheduledTime start, ScheduledTime end) {
        Date startDT = start.getDateTime().toDate();

        SortedSet<ScheduledTime> scheduledTimes = new TreeSet<ScheduledTime>();
        if (cronExpression.isSatisfiedBy(startDT) && start.getDateTime().isBefore(end.getDateTime())) {
            scheduledTimes.add(start);
        }

        DateTime candidateTime = start.getDateTime();

        while((candidateTime = getNextDateTime(candidateTime)) != null &&
                candidateTime.isBefore(end.getDateTime())) {

            scheduledTimes.add(new ScheduledTime(candidateTime));
        }
        return scheduledTimes;
    }

    private DateTime getNextDateTime(DateTime candidateTime) {
        Date date = cronExpression.getNextValidTimeAfter(candidateTime.toDate());
        if (date != null) {
            return new DateTime(date).withZone(DateTimeZone.UTC);
        }
        return null;
    }

}

@@ -1132,62 +1132,8 @@
 ) %7B%0A
-        Date startDT = start.getDateTime().toDate();%0A%0A
     
@@ -1204,24 +1204,117 @@
 ledTime%3E();%0A
+        DateTime startDT = start.getDateTime();%0A        DateTime endDT = end.getDateTime();%0A%0A
         if (
@@ -1349,16 +1349,25 @@
 (startDT
+.toDate()
 ) && sta
@@ -1372,49 +1372,25 @@
 tart
-.getDateTime().isBefore(end.getDateTime()
+DT.isBefore(endDT
 )) %7B
@@ -1470,20 +1470,16 @@
 date
-Time
  = start
 .get
@@ -1474,32 +1474,19 @@
  = start
-.getDateTime();%0A
+DT;
 %0A       
@@ -1502,20 +1502,16 @@
 andidate
-Time
  = getNe
@@ -1530,20 +1530,16 @@
 andidate
-Time
 )) != nu
@@ -1547,24 +1547,8 @@
 l &&
-%0A               
  can
@@ -1553,20 +1553,16 @@
 andidate
-Time
 .isBefor
@@ -1570,28 +1570,15 @@
 (end
-.getDateTime()
+DT
 )) %7B%0A
-%0A
     
@@ -1631,20 +1631,16 @@
 andidate
-Time
 ));%0A    
@@ -1637,32 +1637,41 @@
 te));%0A        %7D%0A
+        %0A
         return s
@@ -1747,20 +1747,16 @@
 andidate
-Time
 ) %7B%0A    
@@ -1817,20 +1817,16 @@
 andidate
-Time
 .toDate(
@@ -1897,19 +1897,10 @@
 date
-).withZone(
+, 
 Date
@@ -1915,33 +1915,44 @@
 .UTC);%0A        %7D
-%0A
+ else %7B%0A    
         return n
@@ -1956,16 +1956,26 @@
 n null;%0A
+        %7D%0A
     %7D%0A%0A%7D

Refactor code for consistency with other schedule implementations.