package com.wonderpush.sdk.remoteconfig;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.ResponseHandlerInterface;
import com.wonderpush.sdk.WonderPush;
import cz.msebera.android.httpclient.Header;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class AsyncHttpClientRemoteConfigFetcher implements RemoteConfigFetcher {
    @Nonnull
    AsyncHttpClient client = new AsyncHttpClient(); // to allow any HTTPS certificate use: new AsyncHttpClient(true, 80, 443);
    @Nonnull
    String clientId;
    public AsyncHttpClientRemoteConfigFetcher(String clientId) {
        this.clientId = clientId;
    }

    @Override
    public void fetchRemoteConfig(@Nullable String version, @Nonnull RemoteConfigHandler handler) {
        String url = String.format("%s%s",Constants.REMOTE_CONFIG_BASE_URL, clientId);
        client.get(url, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                if (statusCode != 200) {
                    handler.handle(null, new Exception("Invalid status code from remote config server:" + statusCode));
                    return;
                }

                String version = response.optString("_configVersion");
                long maxAge = response.optLong("_configMaxAge", Constants.REMOTE_CONFIG_DEFAULT_MAXIMUM_CONFIG_AGE);
                if (version != null) {
                    RemoteConfig config = RemoteConfig.with(response, version, DateHelper.now(), maxAge);
                    handler.handle(config, null);
                    return;
                }
                handler.handle(null, new Exception("Invalid remote config format"));
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
                handler.handle(null, new Exception("Invalid response from remote config server"));
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                handler.handle(null, throwable);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
                handler.handle(null, throwable);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
                handler.handle(null, throwable);
            }
        });
    }
}

@@ -651,24 +651,86 @@
 g clientId;%0A
+    @Nonnull%0A    private SafeDeferProvider safeDeferProvider;%0A
     public A
@@ -778,16 +778,53 @@
 clientId
+, SafeDeferProvider safeDeferProvider
 ) %7B%0A    
@@ -849,24 +849,172 @@
 = clientId;%0A
+        this.safeDeferProvider = safeDeferProvider;%0A    %7D%0A%0A    public interface SafeDeferProvider %7B%0A        void safeDefer(Runnable r, long defer);%0A
     %7D%0A%0A    @
@@ -1209,16 +1209,69 @@
 entId);%0A
+        this.safeDeferProvider.safeDefer(() -%3E %7B%0A    
         
@@ -1322,32 +1322,36 @@
 ) %7B%0A            
+    
 @Override%0A      
@@ -1348,32 +1348,36 @@
 ide%0A            
+  
+  
 public void onSu
@@ -1451,24 +1451,28 @@
             
+    
 if (statusCo
@@ -1496,32 +1496,36 @@
                 
+ 
+   
 handler.handle(n
@@ -1604,24 +1604,28 @@
 atusCode));%0A
+    
             
@@ -1648,35 +1648,43 @@
                 
-%7D%0A%0A
+    %7D%0A%0A    
                 
@@ -1738,16 +1738,20 @@
 sion%22);%0A
+    
         
@@ -1871,24 +1871,28 @@
             
+ 
+   
 if (version 
@@ -1898,24 +1898,28 @@
  != null) %7B%0A
+    
             
@@ -2024,32 +2024,36 @@
                 
+    
 handler.handle(c
@@ -2078,32 +2078,36 @@
                 
+   
+ 
 return;%0A        
@@ -2106,34 +2106,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2213,32 +2213,36 @@
 ));%0A            
+    
 %7D%0A%0A            @
@@ -2232,32 +2232,36 @@
  %7D%0A%0A            
+ 
+   
 @Override%0A      
@@ -2246,32 +2246,36 @@
       @Override%0A
+    
             publ
@@ -2356,32 +2356,36 @@
                 
+    
 handler.handle(n
@@ -2455,35 +2455,43 @@
 ));%0A            
+   
+ 
 %7D%0A%0A
+    
             @Ove
@@ -2488,32 +2488,36 @@
       @Override%0A
+    
             publ
@@ -2610,24 +2610,28 @@
 hrowable) %7B%0A
+    
             
@@ -2671,35 +2671,43 @@
 e);%0A            
-%7D%0A%0A
+    %7D%0A%0A    
             @Ove
@@ -2704,32 +2704,36 @@
       @Override%0A
+    
             publ
@@ -2840,32 +2840,36 @@
                 
+    
 handler.handle(n
@@ -2889,35 +2889,43 @@
 e);%0A            
-%7D%0A%0A
+    %7D%0A%0A    
             @Ove
@@ -2922,32 +2922,36 @@
       @Override%0A
+    
             publ
@@ -3059,32 +3059,36 @@
                 
+    
 handler.handle(n
@@ -3120,19 +3120,42 @@
     
-%7D%0A        %7D
+    %7D%0A            %7D);%0A        %7D, 0
 );%0A 

allow fetcher to run on a thread specified by caller.