package org.wheelmap.android.net;
import android.net.Uri;
import android.util.Log;
import org.wheelmap.android.model.api.ApiResponse;
import org.wheelmap.android.model.api.MeasurementImageUploadResponse;
import org.wheelmap.android.model.api.MeasurementInfo;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import rx.subjects.BehaviorSubject;
public class UploadTangoMeasurementExecutor {
public enum Status {
ERROR,
SUCCESS
}
private static final String TAG = UploadTangoMeasurementExecutor.class.getSimpleName();
/**
* temporary upload measurements over the photos api
*/
private static boolean USE_PHOTO_API = false;
private long wmId;
private MeasurementInfo measurementInfo;
private Uri uploadPhotoUri;
private Observable<MeasurementImageUploadResponse> imageUploadObservable;
private BehaviorSubject<Status> uploadReadySubject = BehaviorSubject.create();
public UploadTangoMeasurementExecutor(long wmId) {
this.wmId = wmId;
}
public Observable<MeasurementImageUploadResponse> uploadImage(Uri uri) {
if (uploadPhotoUri != null && uploadPhotoUri != uri) {
throw new IllegalStateException("UploadTangoMeasurementExecutor can only be used once");
}
uploadPhotoUri = uri;
if (imageUploadObservable == null) {
if (USE_PHOTO_API) {
imageUploadObservable = ApiModule.getInstance().api().uploadImage(wmId, uri)
.flatMap(new Func1<ApiResponse, Observable<ApiResponse>>() {
@Override
public Observable<ApiResponse> call(ApiResponse apiResponse) {
Log.d(TAG, "Upload Response:" + apiResponse);
if (apiResponse.isOk()) {
return Observable.just(apiResponse);
}
return Observable.error(new Exception());
}
}).map(new Func1<ApiResponse, MeasurementImageUploadResponse>() {
@Override
public MeasurementImageUploadResponse call(ApiResponse apiResponse) {
return null;
}
});
} else {
imageUploadObservable = ApiModule.getInstance().api().uploadMeasurementImage(wmId, uri);
}
imageUploadObservable = imageUploadObservable
.subscribeOn(Schedulers.io())
.retry(2)
.replay(1)
.autoConnect();
imageUploadObservable.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
Log.d(TAG, "" + o);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
imageUploadObservable = null;
throwable.printStackTrace();
}
});
}
return imageUploadObservable;
}
public void uploadMetaData(final MeasurementInfo measurementInfo) {
this.measurementInfo = measurementInfo;
uploadImage(uploadPhotoUri).take(1)
.flatMap(new Func1<MeasurementImageUploadResponse, Observable<?>>() {
@Override
public Observable<Void> call(MeasurementImageUploadResponse o) {
if (USE_PHOTO_API) {
return Observable.<Void>just(null)
.delay(1, TimeUnit.SECONDS);
} else {
return ApiModule.getInstance().api().uploadMeasurementMetaData(wmId, o, measurementInfo)
.subscribeOn(Schedulers.io())
.retry(2);
}
}
})
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
uploadReadySubject.onNext(Status.SUCCESS);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
uploadReadySubject.onNext(Status.ERROR);
}
});
}
public Observable<Status> uploadReady() {
return uploadReadySubject.observeOn(AndroidSchedulers.mainThread());
}
public void retry() {
uploadMetaData(measurementInfo);
}
}