package yuku.alkitab.base.devotion;
import android.app.Notification;
import android.content.Intent;
import android.net.Uri;
import android.os.SystemClock;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import yuku.alkitab.base.App;
import yuku.alkitab.base.S;
import yuku.alkitab.base.ac.DevotionActivity;
import yuku.alkitab.base.util.Foreground;
import yuku.alkitab.base.widget.Localized;
import yuku.alkitab.debug.BuildConfig;
import yuku.alkitab.debug.R;
import java.io.IOException;
import java.util.LinkedList;
public class DevotionDownloader extends Thread {
private static final String TAG = DevotionDownloader.class.getSimpleName();
public static final String ACTION_DOWNLOADED = DevotionDownloader.class.getName() + ".action.DOWNLOADED";
private final LinkedList<DevotionArticle> queue_ = new LinkedList<>();
private static final String NOTIFY_TAG = "devotion_downloader";
private static final int NOTIFY_ID = 0;
NotificationManagerCompat nm;
public synchronized boolean add(DevotionArticle article, boolean prioritize) {
if (queue_.contains(article)) return false;
if (prioritize) {
queue_.addFirst(article);
} else {
queue_.add(article);
}
if (!isAlive()) {
start();
}
resumeDownloading();
return true;
}
private synchronized DevotionArticle dequeue() {
while (true) {
if (queue_.size() == 0) {
return null;
}
DevotionArticle article = queue_.getFirst();
queue_.removeFirst();
if (article.getReadyToUse()) {
continue;
}
return article;
}
}
void resumeDownloading() {
synchronized (queue_) {
queue_.notify();
}
}
@Override
public void run() {
//noinspection InfiniteLoopStatement
while (true) {
final DevotionArticle article = dequeue();
if (article == null) {
try {
notifyFinished();
synchronized (queue_) {
queue_.wait();
}
Log.d(TAG, "Downloader is resumed");
} catch (InterruptedException e) {
Log.d(TAG, "Queue is interrupted");
}
} else {
final DevotionActivity.DevotionKind kind = article.getKind();
final String url = BuildConfig.SERVER_HOST + "devotion/get?name=" + kind.name + "&date=" + article.getDate() + "&app_versionCode=" + App.getVersionCode() + "&app_versionName=" + Uri.encode(App.getVersionName());
Log.d(TAG, "Downloader starts downloading name=" + kind.name + " date=" + article.getDate());
notifyDownloadStatus(
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_downloading_title), kind.title),
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_downloading_date), article.getDate())
);
try {
final String output = App.downloadString(url);
// success!
article.fillIn(output);
if (output.startsWith("NG")) {
notifyDownloadStatus(
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_downloading_title), kind.title),
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_error_date), article.getDate(), output)
);
} else {
notifyDownloadStatus(
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_downloading_title), kind.title),
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_success_date), article.getDate())
);
broadcastDownloaded(kind.name, article.getDate());
}
// let's now store it to db
S.getDb().storeArticleToDevotions(article);
} catch (IOException e) {
Log.w(TAG, "@@run", e);
notifyDownloadStatus(
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_downloading_title), kind.title),
TextUtils.expandTemplate(Localized.string(R.string.devotion_downloader_error_date), article.getDate(), e.getMessage())
);
Log.d(TAG, "Downloader failed to download");
}
}
SystemClock.sleep(50);
}
}
void notifyDownloadStatus(final CharSequence title, final CharSequence subtitle) {
Foreground.run(() -> {
if (nm == null) {
nm = NotificationManagerCompat.from(App.context);
}
final Notification n = new NotificationCompat.Builder(App.context)
.setContentTitle(title)
.setContentText(subtitle)
.setProgress(0, 0, true)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(subtitle)
)
.build();
nm.notify(NOTIFY_TAG, NOTIFY_ID, n);
});
}
void broadcastDownloaded(final String name, final String date) {
App.getLbm().sendBroadcast(new Intent(ACTION_DOWNLOADED).putExtra("name", name).putExtra("date", date));
}
void notifyFinished() {
Foreground.run(() -> {
if (nm == null) {
nm = NotificationManagerCompat.from(App.context);
}
nm.cancel(NOTIFY_TAG, NOTIFY_ID);
});
}
}