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

import android.content.Context
import android.content.res.Resources
import app.furmeet.events.system.helper.joinFile
import app.furmeet.events.system.helper.lastPathPart
import app.furmeet.events.system.helper.nullFun
import java.io.File

class OnlinePreloadedCacheManager(context: Context) : CacheManager() {
    private val offCacheMan = OfflineCacheManager(context)
    private val onCacheMan = OnlineCacheManager(context)
    override val goesOnline = true
    override val preloaded = true

    private var updateScheduleManagerNow: () -> Any? = nullFun

    override fun getStamp(file: String) = onCacheMan.getStamp(file) ?: offCacheMan.getStamp(file)
    override fun get(file: String) = onCacheMan[file] ?: offCacheMan[file]
    override fun set(file: String, requestResult: Pair<ByteArray, String>) {
        val prevHash = get(file)?.second
        val currHash = requestResult.second
        onCacheMan[file] = requestResult
        if (file.lastPathPart() == RemoteAssetsHolder.remoteAssets.json.lastPathPart() && currHash != prevHash)
            updateScheduleManagerNow()
    }

    override fun fallbackGet(file: String) = offCacheMan[file]

    override fun delete(file: String) = listOf(onCacheMan.delete(file), offCacheMan.delete(file)).any { it }
    override fun sanitize() = onCacheMan.sanitize() + offCacheMan.sanitize()
    override val files get() = onCacheMan.files + offCacheMan.files
    override fun removeGarbageFiles(): Int {
        val removedFilesCount = mutableListOf<Int>()
        removedFilesCount.add(super.removeGarbageFiles())
        removedFilesCount.add(onCacheMan.removeGarbageFiles())
        val moreGarbage = onCacheMan.files.intersect(offCacheMan.files) - setOf(RemoteAssetsHolder.remoteAssets.json.lastPathPart())
        removedFilesCount.addAll(moreGarbage.map { onCacheMan.delete(it) }.map { if (it) 1 else 0 })
        return removedFilesCount.sum()
    }

    override fun getFileFor(asset: String): File {
        val retFile = onCacheMan.cacheLocation.joinFile(asset.lastPathPart())
        if (!retFile.exists()) {
            val assetDescriptor = get(asset.lastPathPart())
            if (assetDescriptor == null)
                throw Resources.NotFoundException("Unavailable asset: $asset")
            else
                set(asset.lastPathPart(), Pair(assetDescriptor.first.readBytes(), UNIX_TIMESTAMP_START))
        }
        return retFile
    }
}