package dev.inmo.micro_utils.repos.ktor.client.key.values import dev.inmo.micro_utils.ktor.client.createStandardWebsocketFlow import dev.inmo.micro_utils.ktor.common.* import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.ktor.common.one_to_many.onDataClearedRoute import dev.inmo.micro_utils.repos.ktor.common.one_to_many.onNewValueRoute import dev.inmo.micro_utils.repos.ktor.common.one_to_many.onValueRemovedRoute import io.ktor.client.HttpClient import io.ktor.http.ContentType import io.ktor.http.encodeURLQueryComponent import kotlinx.coroutines.flow.Flow import kotlinx.serialization.* class KtorKeyValuesRepoClient ( readDelegate: ReadKeyValuesRepo, writeDelegate: WriteKeyValuesRepo ) : KeyValuesRepo by DelegateBasedKeyValuesRepo( readDelegate, writeDelegate ) { companion object { inline operator fun invoke( baseUrl: String, httpClient: HttpClient, contentType: ContentType, noinline keySerializer: suspend (Key) -> String, onNewValue: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onNewValueRoute), ), onValueRemoved: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onValueRemovedRoute), ), onDataCleared: Flow = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onDataClearedRoute), ), noinline valueSerializer: suspend (Value) -> String ) = KtorKeyValuesRepoClient( KtorReadKeyValuesRepoClient( baseUrl, httpClient, contentType, keySerializer, valueSerializer ), KtorWriteKeyValuesRepoClient( baseUrl, httpClient, contentType, onNewValue, onValueRemoved, onDataCleared ) ) inline operator fun invoke( baseUrl: String, subpart: String, httpClient: HttpClient, contentType: ContentType, noinline keySerializer: suspend (Key) -> String, onNewValue: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onNewValueRoute), ), onValueRemoved: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onValueRemovedRoute), ), onDataCleared: Flow = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onDataClearedRoute), ), noinline valueSerializer: suspend (Value) -> String ) = KtorKeyValuesRepoClient( buildStandardUrl(baseUrl, subpart), httpClient, contentType, keySerializer, onNewValue, onValueRemoved, onDataCleared, valueSerializer ) } } inline fun KtorKeyValuesRepoClient( baseUrl: String, httpClient: HttpClient, contentType: ContentType, keySerializer: SerializationStrategy, valueSerializer: SerializationStrategy, serialFormat: StringFormat, onNewValue: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onNewValueRoute), ), onValueRemoved: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onValueRemovedRoute), ), onDataCleared: Flow = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onDataClearedRoute), ), ) = KtorKeyValuesRepoClient( baseUrl, httpClient, contentType, { serialFormat.encodeToString(keySerializer, it).encodeURLQueryComponent() }, onNewValue, onValueRemoved, onDataCleared ) { serialFormat.encodeToString(valueSerializer, it).encodeURLQueryComponent() } inline fun KtorKeyValuesRepoClient( baseUrl: String, httpClient: HttpClient, contentType: ContentType, keySerializer: SerializationStrategy, valueSerializer: SerializationStrategy, serialFormat: BinaryFormat, onNewValue: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onNewValueRoute), ), onValueRemoved: Flow> = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onValueRemovedRoute), ), onDataCleared: Flow = httpClient.createStandardWebsocketFlow( buildStandardUrl(baseUrl, onDataClearedRoute), ), ) = KtorKeyValuesRepoClient( baseUrl, httpClient, contentType, { serialFormat.encodeHex(keySerializer, it) }, onNewValue, onValueRemoved, onDataCleared ) { serialFormat.encodeHex(valueSerializer, it) }