package app.furmeet.events.system.schedule.managers

import android.content.Context
import app.furmeet.events.system.helper.lastPathPart
import app.furmeet.events.system.helper.nullAndLogIfException
import java.util.concurrent.Future

class FullUpdateCheckerCancellable(context: Context) {
    private val uc = UpdateChecker(context)
    private val promises: MutableList<Future<*>> = mutableListOf()
    private val processedImages: MutableList<String> = mutableListOf()

    fun run(onCompletedCallback: (Boolean) -> Any? = {}) {
        promises.add(uc.downloadBaseJsonWithWatcher { downloadState: UpdateChecker.DownloadState, bytes: ByteArray?, _: Throwable? ->
            when (downloadState) {
                UpdateChecker.DownloadState.ERROR -> {
                    onCompletedCallback(false)
                }
                UpdateChecker.DownloadState.SUCCESS -> {
                    val conventionSeries = nullAndLogIfException { ConventionJsonReader.readFromByteArray(bytes!!) }
                    if (conventionSeries == null) {
                        onCompletedCallback(false)
                    } else {
                        val allImages = conventionSeries.allImages.flatMap { it.values }.distinct()
                        val countImage = { image: String ->
                            synchronized(::processedImages) {
                                processedImages.add(image)
                                if (processedImages.size >= allImages.size) {
                                    uc.deleteGarbage()
                                    onCompletedCallback(true)
                                }
                            }
                        }
                        allImages.forEach { image: String ->
                            if (uc.cacheManager[image.lastPathPart()] != null)
                                countImage(image)
                            else {
                                val url = RemoteAssetsHolder.remoteAssets.media + image
                                promises.add(uc.downloadWithWatcher(url) { ds: UpdateChecker.DownloadState, _: ByteArray?, _: Throwable? ->
                                    if (ds == UpdateChecker.DownloadState.SUCCESS || ds == UpdateChecker.DownloadState.ERROR)
                                        countImage(image)
                                })
                            }
                        }
                    }
                }
                else -> null
            }
        })
    }

    fun stop() {
        promises.forEach { it.cancel(true) }
        promises.clear()
        processedImages.clear()
    }
}