package com.novoda.downloadmanager.lib;
import android.support.v4.util.LongSparseArray;
import com.novoda.downloadmanager.notifications.NotificationVisibility;
import java.util.List;
public class DownloadBatch {
public static final DownloadBatch DELETED = new DownloadBatch(-1, null, null, -1, -1L, -1L);
private final long batchId;
private final BatchInfo info;
private final List<FileDownloadInfo> downloads;
private final int status;
private final long totalSizeBytes;
private final long currentSizeBytes;
public DownloadBatch(long batchId, BatchInfo info, List<FileDownloadInfo> downloads, int status, long totalSizeBytes, long currentSizeBytes) {
this.batchId = batchId;
this.info = info;
this.downloads = downloads;
this.status = status;
this.totalSizeBytes = totalSizeBytes;
this.currentSizeBytes = currentSizeBytes;
}
public long getBatchId() {
return batchId;
}
public long getTotalSize() {
return totalSizeBytes;
}
public long getCurrentSize() {
return currentSizeBytes;
}
public BatchInfo getInfo() {
return info;
}
public List<FileDownloadInfo> getDownloads() {
return downloads;
}
public int getStatus() {
return status;
}
public boolean isQueuedForWifi() {
return this.status == DownloadStatus.QUEUED_FOR_WIFI;
}
public boolean isRunning() {
return this.status == DownloadStatus.RUNNING;
}
public boolean isError() {
return DownloadStatus.isError(status);
}
public boolean isCancelled() {
return DownloadStatus.isCancelled(status);
}
public boolean isSuccess() {
return DownloadStatus.isSuccess(status);
}
public boolean isDeleted() {
return this == DELETED;
}
/**
* Return time when this download will be ready for its next action, in
* milliseconds after given time.
*
* @return If {@code 0}, download is ready to proceed immediately. If
* {@link Long#MAX_VALUE}, then download has no future actions.
*/
public long nextActionMillis(long now, long nextRetryTimeMillis) {
for (FileDownloadInfo info : downloads) {
long individualRetryTimeMillis = getNextActionMillisFor(now, info);
nextRetryTimeMillis = Math.min(individualRetryTimeMillis, nextRetryTimeMillis);
}
return nextRetryTimeMillis;
}
private long getNextActionMillisFor(long now, FileDownloadInfo info) {
if (DownloadStatus.isCompleted(status)) {
return Long.MAX_VALUE;
}
if (status != DownloadStatus.WAITING_TO_RETRY) {
return 0;
}
long when = info.restartTime(now);
if (when <= now) {
return 0;
}
return when - now;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DownloadBatch that = (DownloadBatch) o;
return batchId == that.batchId;
}
@Override
public int hashCode() {
return (int) (batchId ^ (batchId >>> 32));
}
public boolean prune(DownloadDeleter downloadDeleter) {
boolean isDeleted = false;
for (FileDownloadInfo info : downloads) {
if (info.isDeleted()) {
downloadDeleter.deleteFileAndDatabaseRow(info);
isDeleted = true;
} else if (DownloadStatus.isCancelled(info.getStatus()) || DownloadStatus.isError(info.getStatus())) {
downloadDeleter.deleteFileAndMediaReference(info);
isDeleted = true;
}
}
return isDeleted;
}
public boolean isActive() {
return status == DownloadStatus.SUBMITTED || status == DownloadStatus.RUNNING;
}
public boolean scanCompletedMediaIfReady(DownloadScanner downloadScanner) {
for (FileDownloadInfo info : downloads) {
if (info.startScanIfReady(downloadScanner)) {
return true;
}
}
return false;
}
public boolean shouldShowActiveItem() {
int visibility = info.getVisibility();
return visibility == NotificationVisibility.ONLY_WHEN_ACTIVE
|| visibility == NotificationVisibility.ACTIVE_OR_COMPLETE;
}
public boolean shouldShowCompletedItem() {
int visibility = info.getVisibility();
return visibility == NotificationVisibility.ONLY_WHEN_COMPLETE
|| visibility == NotificationVisibility.ACTIVE_OR_COMPLETE;
}
public String getBigPictureUrl() {
return info.getBigPictureUrl();
}
public String getDescription() {
return info.getDescription();
}
public String getTitle() {
return info.getTitle();
}
public long getFirstDownloadBatchId() {
return downloads.get(0).getId();
}
public Statistics getLiveStatistics(LongSparseArray<Long> downloadSpeed) {
long currentBytes = 0;
long totalBytes = 0;
long totalBytesPerSecond = 0;
for (FileDownloadInfo info : downloads) {
if (info.hasTotalBytes()) {
currentBytes += info.getCurrentBytes();
totalBytes += info.getTotalBytes();
Long bytesPerSecond = downloadSpeed.get(info.getId());
if (bytesPerSecond != null) {
totalBytesPerSecond += bytesPerSecond;
}
}
}
return new Statistics(currentBytes, totalBytes, totalBytesPerSecond);
}
public static class Statistics {
private final long currentBytes;
private final long totalBytes;
private final long totalBytesPerSecond;
public Statistics(long currentBytes, long totalBytes, long totalBytesPerSecond) {
this.currentBytes = currentBytes;
this.totalBytes = totalBytes;
this.totalBytesPerSecond = totalBytesPerSecond;
}
public int getPercentComplete() {
if (totalBytes > 0) {
return (int) ((currentBytes * 100) / totalBytes);
} else {
return 0;
}
}
public long getTimeRemaining() {
if (totalBytesPerSecond > 0) {
return ((totalBytes - currentBytes) * 1000) / totalBytesPerSecond;
} else {
return 0;
}
}
}
}