package com.adjust.sdk;

import android.net.Uri;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.URI;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * Created by pfms on 07/11/14.
 */
public class AttributionHandler implements IAttributionHandler{
    private ScheduledExecutorService scheduler;
    private ScheduledExecutorService maxTimeScheduler;
    private IActivityHandler activityHandler;
    private Logger logger;
    private String url;
    private ScheduledFuture waitingTask;

    public AttributionHandler(IActivityHandler activityHandler, ActivityPackage attributionPackage) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        this.activityHandler = activityHandler;
        logger = AdjustFactory.getLogger();
        url = buildUrl(attributionPackage).toString();
    }

    public void getAttribution() {
        if (waitingTask != null) {
            waitingTask.cancel(false);
        }
        getAttribution(0);
    }

    public void checkAttribution(final JSONObject jsonResponse) {
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                checkAttributionInternal(jsonResponse);
            }
        }, 0, TimeUnit.MILLISECONDS);
    }

    private void getAttribution(int delayInMilliseconds) {
        waitingTask = scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                getAttributionInternal();
            }
        }, 0, TimeUnit.MILLISECONDS);
    }

    private void checkAttributionInternal(JSONObject jsonResponse) {
        if (jsonResponse == null) return;

        JSONObject attributionJson = jsonResponse.optJSONObject("attribution");
        Attribution attribution = Attribution.fromJson(attributionJson);

        Integer timerMilliseconds = null;
        try {
            timerMilliseconds = jsonResponse.getInt("ask_in");
        } catch (JSONException e) {
        }

        if (attribution != null && timerMilliseconds == null) {
            attribution.finalAttribution = true;
        }

        activityHandler.updateAttribution(attribution);

        if (timerMilliseconds == null) {
            activityHandler.launchAttributionDelegate();
            return;
        }

        getAttribution(timerMilliseconds);
    }

    private void getAttributionInternal() {
        HttpResponse httpResponse = null;
        try {
            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet();
            request.setURI(new URI(url));
            httpResponse = client.execute(request);
        } catch (Exception e) {
            logger.error("Failed to get attribution (%s)", e.getMessage());
            return;
        }

        JSONObject jsonResponse = Util.parseJsonResponse(httpResponse, logger);

        }
        checkAttributionInternal(jsonResponse);
    }

    private Uri buildUrl(ActivityPackage attributionPackage) {
        Uri.Builder uriBuilder = new Uri.Builder();

        uriBuilder.scheme(Constants.SCHEME);
        uriBuilder.authority(Constants.AUTHORITY);
        uriBuilder.appendPath(attributionPackage.getPath());

        for (Map.Entry<String, String> entity : attributionPackage.getParameters().entrySet()) {
            uriBuilder.appendQueryParameter(entity.getKey(), entity.getValue());
        }

        return uriBuilder.build();
    }
}

@@ -2242,67 +2242,11 @@
     
-Integer timerMilliseconds = null;%0A        try %7B%0A           
+int
  tim
@@ -2275,18 +2275,18 @@
 esponse.
-ge
+op
 tInt(%22as
@@ -2290,27 +2290,32 @@
 %22ask_in%22
+, -1
 );%0A
+%0A
         
 %7D catch 
@@ -2310,32 +2310,33 @@
     
-%7D catch (JSONException e
+if (timerMilliseconds %3C 0
 ) %7B%0A
@@ -2347,132 +2347,178 @@
     
-%7D%0A%0A
     
-    if (attribution != null && timerMilliseconds == null) %7B%0A            attribution.finalAttribution = true;%0A
+boolean updated = activityHandler.updateAttribution(attribution);%0A%0A            if (updated) %7B%0A                activityHandler.launchAttributionDelegate();%0A   
         
 %7D%0A%0A 
@@ -2505,35 +2505,40 @@
 e();%0A           
+ 
 %7D%0A%0A
+    
         activity
@@ -2537,38 +2537,41 @@
 activityHandler.
-update
+setAsking
 Attribution(attr
@@ -2562,35 +2562,29 @@
 Attribution(
-attribution
+false
 );%0A%0A        
@@ -2587,45 +2587,31 @@
     
-if (timerMilliseconds == null) %7B%0A
+    return;%0A    
     
+%7D%0A%0A
     
@@ -2622,38 +2622,41 @@
 activityHandler.
-launch
+setAsking
 AttributionDeleg
@@ -2650,36 +2650,33 @@
 ribution
-Delegate(
+(true
 );%0A
+%0A
         
     retu
@@ -2663,34 +2663,88 @@
 );%0A%0A        
-    return
+if (waitingTask != null) %7B%0A            waitingTask.cancel(false)
 ;%0A        %7D%0A

Check attribution internal