package com.novoda.downloadmanager.lib;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import com.novoda.notils.string.StringUtils;
import java.util.Arrays;
import java.util.List;
class BatchStatusRepository {
private final ContentResolver resolver;
private final DownloadsUriProvider downloadsUriProvider;
private final SystemFacade systemFacade;
private final Uri batchesUri;
private final Uri downloadsUri;
private final Statuses statuses = new Statuses();
BatchStatusRepository(ContentResolver resolver, DownloadsUriProvider downloadsUriProvider, SystemFacade systemFacade) {
this.resolver = resolver;
this.downloadsUriProvider = downloadsUriProvider;
this.systemFacade = systemFacade;
this.batchesUri = downloadsUriProvider.getBatchesUri();
this.downloadsUri = downloadsUriProvider.getAllDownloadsUri();
}
int getBatchStatus(long batchId) {
Cursor cursor = queryForStatus(batchId);
try {
return marshallToStatus(cursor);
} finally {
cursor.close();
}
}
private Cursor queryForStatus(long batchId) {
String[] projection = {DownloadContract.Batches.COLUMN_STATUS};
Cursor cursor = resolver.query(downloadsUriProvider.getSingleBatchUri(batchId), projection, null, null, null);
if (cursor == null) {
throw new BatchRetrievalException(batchId);
}
return cursor;
}
private int marshallToStatus(Cursor cursor) {
cursor.moveToFirst();
return cursor.getInt(cursor.getColumnIndexOrThrow(DownloadContract.Batches.COLUMN_STATUS));
}
int calculateBatchStatusFromDownloads(long batchId) {
Cursor cursor = queryForDownloadStatusesByBatch(batchId);
statuses.clear();
try {
marshallInStatuses(cursor);
} finally {
cursor.close();
}
if (statuses.hasErrorStatus()) {
return statuses.getFirstErrorStatus();
}
if (statuses.hasOnlyCompleteAndSubmittedStatuses()) {
return DownloadStatus.RUNNING;
}
return statuses.getFirstStatusByPriority();
}
private Cursor queryForDownloadStatusesByBatch(long batchId) {
String[] projection = {DownloadContract.Downloads.COLUMN_STATUS};
String[] selectionArgs = {String.valueOf(batchId)};
String selection = DownloadContract.Downloads.COLUMN_BATCH_ID + " = ?";
Cursor cursor = resolver.query(downloadsUriProvider.getAllDownloadsUri(), projection, selection, selectionArgs, null);
if (cursor == null) {
throw new BatchRetrievalException(batchId);
}
return cursor;
}
private void marshallInStatuses(Cursor cursor) {
while (cursor.moveToNext()) {
int statusCode = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadContract.Downloads.COLUMN_STATUS));
statuses.incrementCountFor(statusCode);
}
}
int updateBatchToPendingStatus(@NonNull List<String> batchIds) {
ContentValues values = new ContentValues(1);
values.put(DownloadContract.Batches.COLUMN_STATUS, DownloadStatus.PENDING);
int batchIdsSize = batchIds.size();
String[] whereArray = new String[batchIdsSize];
String[] selectionArgs = new String[batchIdsSize];
for (int i = 0; i < batchIdsSize; i++) {
whereArray[i] = DownloadContract.Batches._ID + " = ?";
selectionArgs[i] = batchIds.get(i);
}
String where = StringUtils.join(Arrays.asList(whereArray), " or ");
return resolver.update(batchesUri, values, where, selectionArgs);
}
void cancelBatch(long batchId) {
setBatchItemsCancelled(batchId);
updateBatchStatus(batchId, DownloadStatus.CANCELED);
}
void updateBatchStatus(long batchId, int status) {
ContentValues values = new ContentValues();
values.put(DownloadContract.Batches.COLUMN_STATUS, status);
values.put(DownloadContract.Batches.COLUMN_LAST_MODIFICATION, systemFacade.currentTimeMillis());
resolver.update(ContentUris.withAppendedId(batchesUri, batchId), values, null, null);
}
void setBatchItemsCancelled(long batchId) {
ContentValues values = new ContentValues(1);
values.put(DownloadContract.Downloads.COLUMN_STATUS, DownloadStatus.CANCELED);
resolver.update(downloadsUri, values, DownloadContract.Downloads.COLUMN_BATCH_ID + " = ?", new String[]{String.valueOf(batchId)});
}
void setBatchItemsFailed(long batchId, long excludedDownloadId) {
ContentValues values = new ContentValues(1);
values.put(DownloadContract.Downloads.COLUMN_STATUS, DownloadStatus.BATCH_FAILED);
String selection = DownloadContract.Downloads.COLUMN_BATCH_ID + " = ? AND " + DownloadContract.Downloads._ID + " <> ? ";
String[] selectionArgs = {String.valueOf(batchId), String.valueOf(excludedDownloadId)};
resolver.update(downloadsUri, values, selection, selectionArgs);
}
}