/*
 * Copyright 2014 Effektif GmbH.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.effektif.workflow.impl.workflow;

import com.effektif.workflow.api.Configuration;
import com.effektif.workflow.api.workflow.Timer;
import com.effektif.workflow.api.workflowinstance.TimerInstance;
import com.effektif.workflow.impl.WorkflowParser;
import com.effektif.workflow.impl.job.Job;
import com.effektif.workflow.impl.job.TimerType;
import com.effektif.workflow.impl.job.TimerTypeService;
import com.effektif.workflow.impl.workflowinstance.ScopeInstanceImpl;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;

import java.time.Duration;
import java.util.Date;


/**
 * @author Tom Baeyens
 */
public class TimerImpl {
  
  public String id;
  public ScopeImpl parent;
  public Configuration configuration;
  public WorkflowImpl workflow;
  public Timer timer;
  public TimerType timerType;

  public void parse(Timer timer, ScopeImpl parentImpl, WorkflowParser parser) {
    this.configuration = parser.configuration;
    this.timer = timer;
    this.id = timer.getId();
    if (parentImpl!=null) {
      this.parent = parentImpl;
      this.workflow = parentImpl.workflow;
    }

    if (timer.getRepeatExpression() != null && timer.getDueDateExpression() != null) {
      parser.addError("TimeDuration and TimeDate on TimerEventDefinition are both set, but mutually exclusive, please remove one of them.");
    }

    TimerTypeService timerTypeService = parser.getConfiguration(TimerTypeService.class);
    this.timerType = timerTypeService.instantiateTimerType(timer);
    // some activity types need to validate incoming and outgoing transitions, 
    // that's why they are NOT parsed here, but after the transitions.
    if (this.timerType==null) {
      parser.addError("Activity '%s' has no activityType configured", id);
    }
  }

  // TODO add a section in ScopeInstanceImpl.toScopeInstance that 
  // uses this method when serializing timers in 
  public Timer toTimer() {
    Timer timer = new Timer();
    // TODO serialize this into a timer
    return timer;
  }

  public TimerInstance toTimerInstance() {
    TimerInstance instance = new TimerInstance();

//    instance.setDueDate(timerType.);

    return instance;
  }

  public Job createJob(ScopeInstanceImpl scopeInstance) {
    Job job = new Job();
    job.workflowId = scopeInstance.workflow.id;
    job.workflowInstanceId = scopeInstance.workflowInstance.id;
    job.dueDate = calculateDueDate();
    job.jobType = timerType.getJobType(scopeInstance, this);
    return job;
  }

  private LocalDateTime calculateDueDate() {

    String repeatExpression = timer.getRepeatExpression();

    if (repeatExpression != null) {
      Duration f = Duration.parse(timer.getRepeatExpression());
      Date date = new Date();
      return new LocalDateTime(date.getTime() + (f.getSeconds() * 1000), DateTimeZone.UTC);
    }

    return null;

  }

}

@@ -1139,23 +1139,166 @@
 e;%0A%0A
-import java.tim
+//import org.joda.time.Duration;%0Aimport javax.xml.datatype.DatatypeConfigurationException;%0Aimport javax.xml.datatype.DatatypeFactory;%0Aimport javax.xml.datatyp
 e.Du
@@ -2961,24 +2961,36 @@
 Instance) %7B%0A
+    try %7B%0A  
     Job job 
@@ -2998,24 +2998,26 @@
  new Job();%0A
+  
     job.work
@@ -3052,24 +3052,26 @@
 low.id;%0A    
+ 
+ 
 job.workflow
@@ -3118,24 +3118,26 @@
 nce.id;%0A    
+  
 job.dueDate 
@@ -3158,24 +3158,26 @@
 Date();%0A    
+ 
+ 
 job.jobType 
@@ -3217,24 +3217,26 @@
 nce, this);%0A
+  
     return j
@@ -3239,16 +3239,110 @@
 rn job;%0A
+    %7D catch (DatatypeConfigurationException ex) %7B%0A      throw new RuntimeException(ex);%0A    %7D%0A
   %7D%0A%0A  p
@@ -3380,16 +3380,54 @@
 ueDate()
+ throws DatatypeConfigurationException
  %7B%0A%0A    
@@ -3536,16 +3536,90 @@
 tion f =
+ DatatypeFactory.newInstance().newDuration(timer.getRepeatExpression());//
  Duratio
@@ -3807,11 +3807,10 @@
 l;%0A%0A  %7D%0A
-%0A
 %7D%0A

Fix jdk7 incompatibility with Duration