package com.arcao.trackables.ui.task;
import android.content.Intent;
import android.os.AsyncTask;
import com.arcao.geocaching.api.data.Trackable;
import com.arcao.geocaching.api.data.TrackableTravel;
import com.arcao.geocaching.api.util.GeocachingUtils;
import com.arcao.trackables.data.service.DataSource;
import com.arcao.trackables.data.service.GeocacheService;
import com.arcao.trackables.data.service.TrackableService;
import com.arcao.trackables.exception.ExceptionHandler;
import java.lang.ref.WeakReference;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import timber.log.Timber;
public class AfterLoginTask extends AsyncTask<Void, AfterLoginTask.TaskListener.ProgressState, Void> {
public interface TaskListener {
void onProgressStateChanged(ProgressState state);
void onTaskFinished(Intent intent);
enum ProgressState {
RETRIEVE_TRACKABLES,
RETRIEVE_TRACKABLE_TRAVELS,
RETRIEVE_GEOCACHES
}
}
@Inject
protected ExceptionHandler exceptionHandler;
@Inject
protected TrackableService trackableService;
@Inject
protected GeocacheService geocacheService;
private final WeakReference<TaskListener> mTaskListenerRef;
private Throwable throwable = null;
public AfterLoginTask(TaskListener listener) {
mTaskListenerRef = new WeakReference<>(listener);
}
@Override
protected Void doInBackground(Void... params) {
try {
publishProgress(TaskListener.ProgressState.RETRIEVE_TRACKABLES);
List<Trackable> trackables = trackableService.getUserTrackables(DataSource.REMOTE).toBlocking().single();
publishProgress(TaskListener.ProgressState.RETRIEVE_TRACKABLE_TRAVELS);
List<String> geocaches = Observable.from(trackables).flatMap(trackable -> trackableService.getTrackableTravel(trackable.getTrackingNumber(), DataSource.REMOTE))
.flatMap(Observable::from)
.filter(trackableTravel -> trackableTravel.getCacheID() > 0)
.distinct(TrackableTravel::getCacheID)
.flatMap(trackableTravel -> Observable.just(GeocachingUtils.cacheIdToCacheCode(trackableTravel.getCacheID())))
.toList()
.toBlocking()
.single();
publishProgress(TaskListener.ProgressState.RETRIEVE_GEOCACHES);
Observable.from(geocaches).flatMap(geocache -> geocacheService.getGeocache(geocache, DataSource.REMOTE)).toList().toBlocking().single();
} catch (Throwable e) {
throwable = e;
if (throwable instanceof RuntimeException && throwable.getCause() != null)
throwable = throwable.getCause();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (throwable != null) {
handleException(throwable);
return;
}
TaskListener listener = mTaskListenerRef.get();
if (listener != null) {
listener.onTaskFinished(null);
}
}
@Override
protected void onProgressUpdate(TaskListener.ProgressState... progress) {
if (progress.length != 1)
return;
TaskListener listener = mTaskListenerRef.get();
if (listener != null) {
listener.onProgressStateChanged(progress[0]);
}
}
protected void handleException(Throwable t) {
if (isCancelled())
return;
Timber.e(t, t.getMessage());
Intent intent = exceptionHandler.handle(t);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
TaskListener listener = mTaskListenerRef.get();
if (listener != null) {
listener.onTaskFinished(intent);
}
}
}