package io.plumery.dropwizard.idempotency;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.core.Response;
import java.io.IOException;

import static org.apache.commons.lang3.StringUtils.isEmpty;

public class IdempotentProviderService {
    private static final Logger log = LoggerFactory.getLogger(IdempotentProviderService.class);
    private final Cache cache;

    public IdempotentProviderService(Cache cache) {
        this.cache = cache;
    }

    public Response idempotent(String idempotencyKey, IdempotentRequestProcessor request) {
        if (isEmpty(idempotencyKey)) {
            return request.process();
        }
        Response response = getResponse(idempotencyKey);
        if (response == null) {
            response = request.process();
            putResponse(idempotencyKey, response);
        }
        return response;
    }

    private void putResponse(String idempotencyKey, Response response) {
        // -- successful response (2xx)
        if (firstNum(response.getStatus()) != 2) {
            return;
        }
        ObjectMapper mapper = new ObjectMapper();
        String responseJson;
        try {
            responseJson = mapper.writeValueAsString(new CachedResponse(response.getEntity(), response.getStatus()));
        } catch (JsonProcessingException e) {
            log.warn("Cannot serialize Response to put into cache: ", e.getMessage());
            return;
        }
        cache.put(idempotencyKey, responseJson);
    }

    private Response getResponse(String idempotencyKey) {
        ObjectMapper mapper = new ObjectMapper();
        String obj = cache.get(idempotencyKey);
        if (obj == null) {
            return null;
        }
        try {
            CachedResponse cachedResponse = mapper.readValue(obj, CachedResponse.class);
            return Response.status(cachedResponse.getStatus()).entity(cachedResponse.getEntity()).build();
        } catch (IOException e) {
            log.warn("Cannot deserialize Response from cache: ", e.getMessage());
        }
        return null;
    }

    private int firstNum(int x) {
        return Integer.parseInt(Integer.toString(x).substring(0, 1));
    }
}

@@ -713,24 +713,70 @@
 encyKey)) %7B%0A
+            // -- no idempotency is requested%0A
             
@@ -803,32 +803,33 @@
 ss();%0A        %7D%0A
+%0A
         Response
@@ -840,26 +840,23 @@
 ponse = 
-getRespons
+retriev
 e(idempo
@@ -932,32 +932,33 @@
 uest.process();%0A
+%0A
             putR
@@ -953,26 +953,127 @@
         
-putRespons
+if (firstNum(response.getStatus()) == 2) %7B%0A                // -- successful response (2xx)%0A                stor
 e(idempo
@@ -1093,16 +1093,30 @@
 ponse);%0A
+            %7D%0A
         
@@ -1170,18 +1170,12 @@
 oid 
-putRespons
+stor
 e(St
@@ -1220,129 +1220,8 @@
 ) %7B%0A
-        // -- successful response (2xx)%0A        if (firstNum(response.getStatus()) != 2) %7B%0A            return;%0A        %7D%0A
     
@@ -1423,24 +1423,77 @@
 Status()));%0A
+            cache.put(idempotencyKey, responseJson);%0A
         %7D ca
@@ -1569,134 +1569,34 @@
 ize 
-R
+r
 esponse
- to put into cache: %22, e.getMessage());%0A            return;%0A        %7D%0A        cache.put(idempotencyKey, responseJson);
+: %22, e);%0A        %7D
 %0A   
@@ -1624,18 +1624,15 @@
 nse 
-getRespons
+retriev
 e(St
@@ -1666,48 +1666,30 @@
     
-ObjectMapper mapper = new ObjectMapper()
+Response answer = null
 ;%0A  
@@ -1726,32 +1726,33 @@
 dempotencyKey);%0A
+%0A
         if (obj 
@@ -1751,17 +1751,17 @@
 if (obj 
-=
+!
 = null) 
@@ -1778,31 +1778,54 @@
     
-return null
+ObjectMapper mapper = new ObjectMapper()
 ;%0A    
-    %7D%0A
     
@@ -1826,32 +1826,36 @@
           try %7B%0A
+    
             Cach
@@ -1943,23 +1943,54 @@
     
-return Response
+    answer = Response%0A                        
 .sta
@@ -2020,16 +2020,41 @@
 tatus())
+%0A                        
 .entity(
@@ -2080,16 +2080,41 @@
 ntity())
+%0A                        
 .build()
@@ -2115,32 +2115,36 @@
 uild();%0A        
+    
 %7D catch (IOExcep
@@ -2145,32 +2145,36 @@
 OException e) %7B%0A
+    
             log.
@@ -2202,46 +2202,22 @@
 ize 
-R
+r
 esponse
- from cache: %22, e.getMessage()
+: %22, e
 );%0A 
@@ -2215,34 +2215,49 @@
  %22, e);%0A        
+    
 %7D%0A
+        %7D%0A%0A
         return n
@@ -2255,20 +2255,22 @@
  return 
-null
+answer
 ;%0A    %7D%0A

simplify the naming and the structure