package io.digdag.util;

import io.digdag.client.config.Config;
//import io.digdag.core.workflow.TaskConfig;

public class RetryControl
{
    public static RetryControl prepare(Config config, Config stateParams, boolean enableByDefault)
    {
        return new RetryControl(config, stateParams, enableByDefault);
    }

    private final Config stateParams;
    private final int retryLimit;
    private final int retryCount;

    private RetryControl(Config config, Config stateParams, boolean enableByDefault)
    {
        this.stateParams = stateParams;
        this.retryLimit = config.get("_retry", int.class, enableByDefault ? 3 : 0);
        this.retryCount = stateParams.get("retry_count", int.class, 0);
    }

    public int getNextRetryInterval()
    {
        // TODO implement exponential wait
        return 0;
    }

    public Config getNextRetryStateParams()
    {
        return stateParams.deepCopy().set("retry_count", retryCount + 1);
    }

    public boolean evaluate()
    {
        return retryLimit > retryCount;
    }
}

@@ -57,16 +57,64 @@
 Config;%0A
+import io.digdag.client.config.ConfigException;%0A
 //import
@@ -179,16 +179,17 @@
 ntrol%0A%7B%0A
+%0A
     publ
@@ -359,24 +359,569 @@
 lt);%0A    %7D%0A%0A
+    private enum RetryIntervalType %7B%0A        CONSTATNT(%22constant%22), EXPONENTIAL(%22exponential%22);%0A        String type;%0A        private RetryIntervalType(final String type) %7B%0A            this.type = type;%0A        %7D%0A        public static RetryIntervalType find(String value) %7B%0A            for (RetryIntervalType r : RetryIntervalType.values()) %7B%0A                if (r.type.equalsIgnoreCase(value)) %7B%0A                    return r;%0A                %7D%0A            %7D%0A            throw new ConfigException(%22Invalid retry_interval_type%22);%0A        %7D%0A    %7D%0A%0A
     private 
@@ -1013,16 +1013,108 @@
 ryCount;
+%0A    private final int retryInterval;%0A    private final RetryIntervalType retryIntervalType;
 %0A%0A    pr
@@ -1256,21 +1256,112 @@
 is.retry
-Limit
+Count = stateParams.get(%22retry_count%22, int.class, 0);%0A%0A        try %7B%0A            String retryStr
  = confi
@@ -1376,27 +1376,30 @@
 retry%22, 
+Str
 in
-t
+g
 .class, 
 enableBy
@@ -1394,199 +1394,1335 @@
 ss, 
-enableByDefault ? 3 : 0);%0A        this.retryCount = stateParams.get(%22retry_count%22, int.class, 0);%0A    %7D%0A%0A    public int getNextRetryInterval()%0A    %7B%0A        // TODO implement exponential wait
+%22%22);%0A            String%5B%5D params = %7B%7D;%0A            if(! retryStr.equals(%22%22)) params = retryStr.split(%22%5C%5Cs+%22, 3);%0A%0A            if (params.length == 0) %7B%0A                this.retryLimit = enableByDefault ? 3 : 0;%0A            %7D else %7B%0A                this.retryLimit = Integer.parseInt(params%5B0%5D);%0A            %7D%0A            if (params.length %3E= 2) %7B%0A                this.retryInterval = Integer.parseInt(params%5B1%5D);%0A            %7D else %7B%0A                this.retryInterval = 0;%0A            %7D%0A            if (params.length %3E= 3) %7B%0A                this.retryIntervalType = RetryIntervalType.find(params%5B2%5D);%0A            %7D else %7B%0A                this.retryIntervalType = RetryIntervalType.CONSTATNT;%0A            %7D%0A        %7D%0A        catch(NumberFormatException nfe)%7B%0A            nfe.printStackTrace();%0A            throw new ConfigException(nfe);%0A        %7D%0A        catch(ConfigException ce)%7B%0A            throw ce;%0A        %7D%0A    %7D%0A%0A    public int getNextRetryInterval()%0A    %7B%0A        int retryCount = stateParams.get(%22retry_count%22, int.class, 0);%0A        int interval = 0;%0A        switch(retryIntervalType) %7B%0A            case CONSTATNT:%0A                interval = retryInterval;%0A                break;%0A            case EXPONENTIAL:%0A                interval = retryInterval * (int)Math.pow(2, retryCount);%0A                break;%0A        %7D
 %0A   
@@ -2733,17 +2733,24 @@
  return 
-0
+interval
 ;%0A    %7D%0A

Implement interval for _retry.