package dev.inmo.postssystem.features.files.client

import dev.inmo.postssystem.features.files.common.*
import dev.inmo.postssystem.features.files.common.storage.ReadFilesStorage
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ktor.client.crud.KtorReadStandardCrudRepo
import io.ktor.client.HttpClient
import io.ktor.client.request.post
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readBytes
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.builtins.nullable

class ClientReadFilesStorage(
    baseUrl: String,
    private val client: HttpClient,
    private val serialFormat: BinaryFormat
) : ReadFilesStorage, ReadCRUDRepo<MetaFileInfoStorageWrapper, FileId> by KtorReadStandardCrudRepo(
    buildStandardUrl(baseUrl, filesRootPathPart),
    UnifiedRequester(client, serialFormat),
    MetaFileInfoStorageWrapper.serializer(),
    MetaFileInfoStorageWrapper.serializer().nullable,
    FileId.serializer()
) {
    private val unifiedRequester = UnifiedRequester(client, serialFormat)
    private val fullFilesPath = buildStandardUrl(baseUrl, filesRootPathPart)
    private val fullFilesGetBytesPath = buildStandardUrl(
        fullFilesPath,
        filesGetFilesPathPart
    )

    override suspend fun getBytes(id: FileId): ByteArray = client.post<HttpResponse>(fullFilesGetBytesPath) {
        body = serialFormat.encodeToByteArray(FileId.serializer(), id)
    }.readBytes()

    override suspend fun getFullFileInfo(
        id: FileId
    ): FullFileInfoStorageWrapper? = unifiedRequester.uniget(
        buildStandardUrl(
            fullFilesPath,
            filesGetFullFileInfoPathPart,
            filesFileIdParameter to unifiedRequester.encodeUrlQueryValue(FileId.serializer(), id)
        ),
        FullFileInfoStorageWrapper.serializer().nullable
    )
}
