package org.wikipedia.useroption.sync;
import android.accounts.Account;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncResult;
import android.os.Bundle;
import org.wikipedia.auth.AccountUtil;
import org.wikipedia.database.http.HttpStatus;
import org.wikipedia.useroption.UserOption;
import org.wikipedia.useroption.database.UserOptionDao;
import org.wikipedia.useroption.database.UserOptionRow;
import org.wikipedia.useroption.dataclient.UserInfo;
import org.wikipedia.useroption.dataclient.UserOptionDataClientSingleton;
import org.wikipedia.util.log.L;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class UserOptionSyncAdapter extends AbstractThreadedSyncAdapter {
public UserOptionSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
if (!AccountUtil.supported(account)) {
L.i("unexpected account=" + account);
++syncResult.stats.numAuthExceptions;
return;
}
boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD);
try {
upload();
if (!uploadOnly) {
download();
}
} catch (IOException e) {
L.d(e);
++syncResult.stats.numIoExceptions;
}
}
private synchronized void download() throws IOException {
UserInfo info = UserOptionDataClientSingleton.instance().get();
Collection<UserOption> options = info.userjsOptions();
L.i("downloaded " + options.size() + " option(s)");
UserOptionDao.instance().reconcileTransaction(options);
}
private synchronized void upload() throws IOException {
List<UserOptionRow> rows = new ArrayList<>(UserOptionDao.instance().startTransaction());
while (!rows.isEmpty()) {
UserOptionRow row = rows.get(0);
try {
if (row.status() == HttpStatus.DELETED) {
L.i("deleting user option: " + row.key());
UserOptionDataClientSingleton.instance().delete(row.key());
} else if (!row.status().synced()) {
L.i("uploading user option: " + row.key());
//noinspection ConstantConditions
UserOptionDataClientSingleton.instance().post(row.dat());
}
} catch (IOException e) {
UserOptionDao.instance().failTransaction(rows);
throw e;
}
UserOptionDao.instance().completeTransaction(row);
rows.remove(0);
}
}
}