package dev.inmo.postssystem.core.content.api.business.content_adapters.binary import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.set import kotlinx.coroutines.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import java.io.File class FilesStoreRepoAdapter( private val filesRepo: KeyValueRepo, private val temporalFilesFolder: File ) : KeyValueRepo { private val File.asByteArray get() = readBytes() override val onNewValue: Flow> = filesRepo.onNewValue.map { (filename, file) -> filename to file.asByteArray } override val onValueRemoved: Flow = filesRepo.onValueRemoved init { temporalFilesFolder.mkdirs() } override suspend fun contains(key: String): Boolean = filesRepo.contains(key) override suspend fun count(): Long = filesRepo.count() override suspend fun get(k: String): ByteArray? = filesRepo.get(k) ?.asByteArray override suspend fun keys( v: ByteArray, pagination: Pagination, reversed: Boolean ): PaginationResult = emptyPaginationResult() override suspend fun keys( pagination: Pagination, reversed: Boolean ): PaginationResult = filesRepo.keys(pagination, reversed) override suspend fun set(toSet: Map) { supervisorScope { toSet.map { (filename, bytes) -> launch { safelyWithoutExceptions { val file = File(temporalFilesFolder, filename).also { it.delete() doOutsideOfCoroutine { it.createNewFile() it.writeBytes(bytes) } } filesRepo.set(filename, file) doOutsideOfCoroutine { file.delete() } } } } }.joinAll() } override suspend fun unset(toUnset: List) = filesRepo.unset(toUnset) override suspend fun values( pagination: Pagination, reversed: Boolean ): PaginationResult = filesRepo.values(pagination, reversed).let { PaginationResult( it.page, it.pagesNumber, it.results.map { it.readBytes() }, it.size ) } }