package cc.softwarefactory.lokki.android.espresso.utilities;

import com.squareup.okhttp.mockwebserver.Dispatcher;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.RecordedRequest;

import org.json.JSONException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class MockDispatcher extends Dispatcher {

    public static final String METHOD_GET = "GET";
    public static final String METHOD_POST = "POST";
    public static final String METHOD_DELETE = "DELETE";
    public static final String DEFAULT_USER_BASE_PATH = "/user/" + TestUtils.VALUE_TEST_USER_ID + "/";

    private Map<String, MockResponse> responses;
    private Map<String, RequestsHandle> requests;

    public MockDispatcher() throws JSONException {
        this.responses = new HashMap<>();
        this.requests = new HashMap<>();
        setDefaultResponses();
    }

    private void setDefaultResponses() throws JSONException {
        setDashboardResponse(new MockResponse().setBody(MockJsonUtils.getEmptyDashboardJson()));
        setPlacesResponse(new MockResponse().setBody(MockJsonUtils.getEmptyPlacesJson()));
    }

    @Override
    public MockResponse dispatch(RecordedRequest recordedRequest) throws InterruptedException {
        System.out.println("RECORDED REQUEST: " + recordedRequest.toString());
        String key = constructKey(recordedRequest.getMethod(), recordedRequest.getPath());
        if (requests.containsKey(key)) {
            requests.get(key).addRequest(recordedRequest);
        }
        return responses.get(key);
    }

    public RequestsHandle setDashboardResponse(MockResponse response) {
        return installResponse(METHOD_GET, DEFAULT_USER_BASE_PATH + "dashboard", response);
    }

    public RequestsHandle setPlacesResponse(MockResponse response) {
        return setPlacesResponse(response, METHOD_GET);
    }

    public RequestsHandle setPlacesResponse(MockResponse response, String method) {
        return installResponse(method, DEFAULT_USER_BASE_PATH + "places", response);
    }

    public RequestsHandle setPlacesDeleteResponse(MockResponse response, String placeId) {
        return installResponse(METHOD_DELETE, DEFAULT_USER_BASE_PATH + "places" + "/" + placeId, response);
    }

    public RequestsHandle setSignUpResponse(MockResponse response) {
        return installResponse(METHOD_POST, "/signup", response);
    }

    public RequestsHandle installResponse(String method, String path, MockResponse response) {
        String key = constructKey(method, path);
        RequestsHandle requestsHandle;

        if (!requests.containsKey(key)) {
            requestsHandle = new RequestsHandle();
            requests.put(key, requestsHandle);
        } else {
            requestsHandle = requests.get(key);
        }

        responses.put(key, response);
        return requestsHandle;
    }

    private String constructKey(String method, String path) {
        return method + " " + path;
    }
}

@@ -275,96 +275,15 @@
 til.
-ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.HashMap;%0Aimport java.util.List
+HashMap
 ;%0Aim
@@ -719,16 +719,238 @@
 uests;%0A%0A
+    /*%0A     * Response dispatching is done in different thread than installing responses, so there's a%0A     * potential for race condition %E2%80%93 thus a lock here.%0A     */%0A    private final Object dispatchLock = new Object();%0A%0A
     publ
@@ -1646,24 +1646,67 @@
 getPath());%0A
+%0A        synchronized (dispatchLock) %7B%0A    
         if (
@@ -1726,32 +1726,36 @@
 ainsKey(key)) %7B%0A
+    
             requ
@@ -1805,18 +1805,26 @@
         
+  
-%7D%0A
+  %7D%0A    
         
@@ -1846,24 +1846,34 @@
 s.get(key);%0A
+        %7D%0A
     %7D%0A%0A    p
@@ -2878,16 +2878,58 @@
 andle;%0A%0A
+        synchronized (dispatchLock) %7B%0A    
         
@@ -2954,32 +2954,36 @@
 ainsKey(key)) %7B%0A
+    
             requ
@@ -3021,32 +3021,36 @@
 ();%0A            
+   
+ 
 requests.put(key
@@ -3076,16 +3076,20 @@
         
+    
 %7D else %7B
@@ -3089,16 +3089,20 @@
  else %7B%0A
+    
         
@@ -3145,27 +3145,35 @@
 y);%0A        
-%7D%0A%0A
+    %7D%0A%0A    
         resp
@@ -3194,24 +3194,35 @@
  response);%0A
+        %7D%0A%0A
         retu

Deal with potential race condition