package com.here.account.oauth2.retry;

import com.here.account.http.HttpProvider;

import java.util.logging.Logger;

/**
 * A {@code RetryExecutor} provides a mechanisms to execute a {@link Retryable}
 * and will retry on failure according to an implementation specific retry policy.
 * */
public class RetryExecutor {

    private final RetryPolicy retryPolicy;
    private static final Logger LOGGER = Logger.getLogger(RetryExecutor.class.getName());

    public RetryExecutor(RetryPolicy retryPolicy) {
        this.retryPolicy = retryPolicy;
    }

    /**
     * Execute the given {@link Retryable} until retry policy decides to give up.
     * @param retryable the {@link Retryable} to execute
     * @return http response return from {@code Retryable}
     * @throws Exception
     */
    public HttpProvider.HttpResponse execute(Retryable retryable) throws Exception {
        RetryContext retryContext = new RetryContext();
        HttpProvider.HttpResponse httpResponse;
        try {
            httpResponse = retryable.execute();
            retryContext.setLastRetryResponse(httpResponse);
        } catch (Exception e) {
            retryContext.setLastException(e);
        }

        while (retryPolicy.shouldRetry(retryContext)) {
            try {
                retryContext.incrementRetryCount();

                int waitInterval = retryPolicy.getNextRetryIntervalMillis(retryContext);

                LOGGER.warning("Retrying after - "+ waitInterval +" milliseconds...");
                try {
                    Thread.sleep(waitInterval);
                } finally {
                    httpResponse = retryable.execute();
                    retryContext.setLastRetryResponse(httpResponse);
                }
            } catch (Exception e) {
                retryContext.setLastException(e);
            }
        }

        if (retryContext.getLastException() != null) {
            throw retryContext.getLastException();
        }

        return retryContext.getLastRetryResponse();
    }
}

@@ -975,16 +975,44 @@
 sponse;%0A
+%0A        while (true) %7B%0A    
         
@@ -1021,32 +1021,36 @@
 y %7B%0A            
+ 
+   
 httpResponse = r
@@ -1061,32 +1061,36 @@
 able.execute();%0A
+    
             retr
@@ -1134,32 +1134,36 @@
 ponse);%0A        
+  
+  
 %7D catch (Excepti
@@ -1162,32 +1162,36 @@
 (Exception e) %7B%0A
+    
             retr
@@ -1220,32 +1220,36 @@
 ion(e);%0A        
+    
 %7D%0A%0A        while
@@ -1243,21 +1243,22 @@
         
-while
+    if
  (retryP
@@ -1292,34 +1292,16 @@
 ext)) %7B%0A
-            try %7B%0A
         
@@ -1614,140 +1614,125 @@
   %7D 
-finally %7B%0A                    httpResponse = retryable.execute();%0A                    retryContext.setLastRetryResponse(httpResponse
+catch (InterruptedException e)%7B%0A                    LOGGER.warning(%22Got InterruptedException while waiting to retry.%22
 );%0A 
@@ -1762,35 +1762,20 @@
       %7D 
-catch (Exception e)
+else
  %7B%0A     
@@ -1789,40 +1789,13 @@
     
+b
 re
-tryContext.setLastException(e)
+ak
 ;%0A  

Implement mechanism for retry with exponential backoff when fetching access token in AAA SDK