package com.rapidftr.service;
import android.util.Log;
import com.google.common.io.CharStreams;
import com.rapidftr.RapidFtrApplication;
import com.rapidftr.model.BaseModel;
import com.rapidftr.utils.http.FluentRequest;
import com.rapidftr.utils.http.FluentResponse;
import org.apache.http.HttpException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.ParameterizedType;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.rapidftr.utils.http.FluentRequest.http;
public class EntityHttpDao<T extends BaseModel> {
private static final String UPDATED_AFTER_FORM_PARAMETER = "updated_after";
private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final String LOCATION_ATTRIBUTE = "location";
protected String serverUrl;
protected String apiPath;
protected String apiParameter;
public EntityHttpDao(RapidFtrApplication application) {
this.serverUrl = application.getCurrentUser().getServerUrl();
}
public EntityHttpDao(RapidFtrApplication application, String serverUrl, String apiPath, String apiParameter) {
this(application);
this.serverUrl = serverUrl;
this.apiPath = apiPath;
this.apiParameter = apiParameter;
}
public T get(String resourceUrl) throws IOException, HttpException {
FluentResponse fluentResponse = http()
.context(RapidFtrApplication.getApplicationInstance())
.host(resourceUrl)
.get()
.ensureSuccess();
return buildEntityFromJson(getJsonResponse(fluentResponse));
}
public InputStream getResourceStream(String resourcePath) throws IOException {
FluentResponse fluentResponse = http()
.context(RapidFtrApplication.getApplicationInstance())
.path(resourcePath)
.get();
return fluentResponse.getEntity().getContent();
}
public T update(T entity, String path, Map<String, String> requestParameters) throws IOException, HttpException {
FluentRequest fluentRequest = http()
.context(RapidFtrApplication.getApplicationInstance())
.path(path)
.param(apiParameter, entity.getJsonString());
if (requestParameters != null && requestParameters.size() > 0) {
Iterator<String> keys = requestParameters.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
fluentRequest.param(key, requestParameters.get(key));
}
}
FluentResponse fluentResponse = fluentRequest.putWithMultiPart().ensureSuccess();
return buildEntityFromJson(getJsonResponse(fluentResponse));
}
public List<String> getUpdatedResourceUrls(DateTime lastUpdate) throws IOException, HttpException, JSONException {
String utcString = new StringBuilder(DateTimeFormat.forPattern(DATE_PATTERN).withZone(DateTimeZone.UTC).print(lastUpdate)).append("UTC").toString();
final FluentResponse fluentResponse = http()
.context(RapidFtrApplication.getApplicationInstance())
.host(serverUrl)
.path(apiPath)
.param(UPDATED_AFTER_FORM_PARAMETER, utcString)
.get()
.ensureSuccess();
String json = getJsonResponse(fluentResponse);
JSONArray jsonArray = new JSONArray(json);
List<String> urls = new ArrayList<String>();
for (int i = 0; i < jsonArray.length(); i++) {
urls.add(jsonArray.getJSONObject(i).getString(LOCATION_ATTRIBUTE));
}
return urls;
}
public T create(T entity, String path, Map<String, String> requestParameters) throws IOException, HttpException {
FluentRequest fluentRequest = http()
.context(RapidFtrApplication.getApplicationInstance())
.path(path)
.param(apiParameter, entity.getJsonString());
if (requestParameters != null && requestParameters.size() > 0) {
Iterator<String> keys = requestParameters.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
fluentRequest.param(key, requestParameters.get(key));
}
}
FluentResponse fluentResponse = fluentRequest.postWithMultiPart().ensureSuccess();
return buildEntityFromJson(getJsonResponse(fluentResponse));
}
protected String getJsonResponse(FluentResponse fluentResponse) throws IOException {
return CharStreams.toString(new InputStreamReader(fluentResponse.getEntity().getContent()));
}
private String buildUpdatePath(T entity) {
StringBuilder builder = new StringBuilder();
builder.append(apiPath.endsWith("/") ? apiPath : apiPath + "/");
builder.append(entity.getInternalId() != null ? entity.getInternalId() : "");
return builder.toString();
}
protected T buildEntityFromJson(String jsonResponse) {
try {
return (T) getGenericParameterClass().getConstructor(String.class).newInstance(jsonResponse);
} catch (Exception e) {
Log.e(null, e.getMessage(), e);
}
return null;
}
protected Class getGenericParameterClass() {
return (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}