package org.sagebionetworks.search;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.sagebionetworks.utils.HttpClientHelper;
import org.sagebionetworks.utils.HttpClientHelperException;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * CloudSearch does not yet provide a Java SDK. This is the bare minimum needed
 * for Search Updates. If we find more uses for this, we'll move it to something
 * under platform/trunk/lib.
 * 
 * @author deflaux
 * 
 */
public class CloudSearchClient {

	private static final Map<String, String> SEND_DOCUMENTS_REQUEST_HEADERS;
	static {
		Map<String, String> requestHeaders = new HashMap<String, String>();
		requestHeaders.put("Content-Type", "application/json;charset=UTF-8");
		SEND_DOCUMENTS_REQUEST_HEADERS = Collections.unmodifiableMap(requestHeaders);
	}

	@Autowired
	CloudSearchHttpClientProvider httpClientProvider;
	
	private HttpClient httpClient;
	private String searchServiceEndpoint;
	private String documentServiceEndpoint;

	public CloudSearchClient(String searchServiceEndpoint, String documentServiceEndpoint) {
		this.httpClient = httpClientProvider.getHttpClient();
		this.searchServiceEndpoint = searchServiceEndpoint;
		this.documentServiceEndpoint = documentServiceEndpoint;
	}

	// For unit test
	public CloudSearchClient(CloudSearchHttpClientProvider httpClientProvider, String searchServiceEndpoint, String documentServiceEndpoint) {
		this.httpClient = httpClientProvider.getHttpClient();
		this.searchServiceEndpoint = searchServiceEndpoint;
		this.documentServiceEndpoint = documentServiceEndpoint;
	}

	public void sendDocuments(String documents) throws ClientProtocolException,
			IOException, HttpClientHelperException {
		HttpClientHelper.postContent(httpClient, documentServiceEndpoint,
				documents, SEND_DOCUMENTS_REQUEST_HEADERS);
	}

	public void sendDocuments(InputStream stream, long length) throws ClientProtocolException, IOException, HttpClientHelperException {
		HttpClientHelper.postStream(httpClient, documentServiceEndpoint,
				stream, length, SEND_DOCUMENTS_REQUEST_HEADERS);
	}

	public String performSearch(String searchQuery) throws ClientProtocolException, IOException, HttpClientHelperException {
		String url = searchServiceEndpoint + "?" + searchQuery;
		return HttpClientHelper.getContent(httpClient, url);
	}
	
}

@@ -1069,16 +1069,60 @@
 ovider;%0A
+%09private final long MAX_BACKOFF_MS = 6400L;%0A
 %09%0A%09priva
@@ -2504,59 +2504,617 @@
 ;%0A%09%09
-return HttpClientHelper.getContent(httpClient, url)
+String s = null;%0A%09%09long backoffMs = 100L;%0A%09%09HttpClientHelperException e = null;%0A%09%09do %7B%0A%09%09%09try %7B%0A%09%09%09%09s = HttpClientHelper.getContent(httpClient, url);%0A%09%09%09%7D catch (HttpClientHelperException e1) %7B%0A%09%09%09%09e = e1;%0A%09%09%09%09if (e1.getHttpStatus() == 507) %7B%0A%09%09%09%09%09try %7B%0A%09%09%09%09%09%09Thread.sleep(backoffMs);%0A%09%09%09%09%09%7D catch (InterruptedException e2) %7B%0A%09%09%09%09%09%09// Continue%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D else %7B%0A%09%09%09%09%09// rethrow%0A%09%09%09%09%09throw(e1);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09backoffMs *= 2;%0A%09%09%7D while ((s == null) && (backoffMs %3C MAX_BACKOFF_MS));%0A%09%09// If we're past the max backoff, throw the last 507 we got%0A%09%09if (backoffMs %3E= MAX_BACKOFF_MS) %7B%0A%09%09%09throw(e);%0A%09%09%7D%0A%09%09return s
 ;%0A%09%7D

Add back off