package co.electriccoin.zcash.configuration.api import co.electriccoin.zcash.configuration.model.entry.ConfigKey import co.electriccoin.zcash.configuration.model.map.Configuration import kotlinx.collections.immutable.PersistentList import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.datetime.Instant class MergingConfigurationProvider(private val configurationProviders: PersistentList) : ConfigurationProvider { override fun peekConfiguration(): Configuration { return MergingConfiguration(configurationProviders.map { it.peekConfiguration() }.toPersistentList()) } override fun getConfigurationFlow(): Flow { return combine(configurationProviders.map { it.getConfigurationFlow() }) { configurations -> MergingConfiguration(configurations.toList()) } } override fun hintToRefresh() { configurationProviders.forEach { it.hintToRefresh() } } } private data class MergingConfiguration(private val configurations: List) : Configuration { override val updatedAt: Instant? get() = configurations.mapNotNull { it.updatedAt }.maxOrNull() override fun hasKey(key: ConfigKey): Boolean { return null != configurations.firstWithKey(key) } override fun getBoolean(key: ConfigKey, defaultValue: Boolean): Boolean { return configurations.firstWithKey(key)?.let { return it.getBoolean(key, defaultValue) } ?: defaultValue } override fun getInt(key: ConfigKey, defaultValue: Int): Int { return configurations.firstWithKey(key)?.let { return it.getInt(key, defaultValue) } ?: defaultValue } override fun getString(key: ConfigKey, defaultValue: String): String { return configurations.firstWithKey(key)?.let { return it.getString(key, defaultValue) } ?: defaultValue } } private fun List.firstWithKey(key: ConfigKey): Configuration? = firstOrNull { it.hasKey(key) }