Repository: corona-warn-app/cwa-app-android
File: Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ccl/dccwalletinfo/calculation/DccWalletInfoCalculation.kt (Kotlin)

Code before:
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.validation.core.rule.DccValidationRule
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.util.serialization.BaseJackson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject

class DccWalletInfoCalculation @Inject constructor(
    @BaseJackson private val mapper: ObjectMapper,
    @BaseGson private val gson: Gson,
    private val jsonFunctionsWrapper: JsonFunctionsWrapper,
) {

    private var boosterRulesNode: JsonNode = NullNode.instance

    fun init(boosterRules: List<DccValidationRule>) {
        boosterRulesNode = gson.toJson(boosterRules).toJsonNode()
    }

    fun getDccWalletInfo(
        dccList: List<CwaCovidCertificate>
    ): DccWalletInfo {

        val output: JsonNode
        runBlocking(Dispatchers.IO) {
            output = jsonFunctionsWrapper.evaluateFunction(
                FUNCTION_NAME,
                getDccWalletInfoInput(dccList = dccList).toJsonNode()
            )
        }
        return mapper.treeToValue(output, DccWalletInfo::class.java)
    }

    @VisibleForTesting
    internal fun getDccWalletInfoInput(
        dccList: List<CwaCovidCertificate>,
        boosterNotificationRules: JsonNode = boosterRulesNode,
        defaultInputParameters: CclInputParameters = getDefaultInputParameters(),
    ) = DccWalletInfoInput(
        os = defaultInputParameters.os,
        language = defaultInputParameters.language,
        now = SystemTime(
            timestamp = defaultInputParameters.now.timestamp,
            localDate = defaultInputParameters.now.localDate,
            localDateTime = defaultInputParameters.now.localDateTime,
            localDateTimeMidnight = defaultInputParameters.now.localDateTimeMidnight,
            utcDate = defaultInputParameters.now.utcDate,
            utcDateTime = defaultInputParameters.now.utcDateTime,
            utcDateTimeMidnight = defaultInputParameters.now.utcDateTimeMidnight,
        ),

Review comment (suggestion):
I think we should switch to the IO Dispatcher in `JsonFunctionsWrapper.evalateFunction()` so that callers of that function can call it on any dispatcher.

Code after:
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.validation.core.rule.DccValidationRule
import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.util.serialization.BaseJackson
import kotlinx.coroutines.withContext
import org.joda.time.DateTime
import javax.inject.Inject

class DccWalletInfoCalculation @Inject constructor(
    @BaseJackson private val mapper: ObjectMapper,
    @BaseGson private val gson: Gson,
    private val cclJsonFunctions: CCLJsonFunctions,
    private val dispatcherProvider: DispatcherProvider
) {

    private var boosterRulesNode: JsonNode = NullNode.instance

    fun init(boosterRules: List<DccValidationRule>) {
        boosterRulesNode = gson.toJson(boosterRules).toJsonNode()
    }

    @Suppress("BlockingMethodInNonBlockingContext")
    suspend fun getDccWalletInfo(
        dccList: List<CwaCovidCertificate>,
        dateTime: DateTime = DateTime.now()
    ): DccWalletInfo = withContext(dispatcherProvider.IO) {
        val output = cclJsonFunctions.evaluateFunction(
            FUNCTION_NAME,
            getDccWalletInfoInput(
                dccList = dccList,
                boosterNotificationRules = boosterRulesNode,
                defaultInputParameters = getDefaultInputParameters(dateTime)
            ).toJsonNode()
        )

        mapper.treeToValue(output, DccWalletInfo::class.java)
    }

    @VisibleForTesting
    internal fun getDccWalletInfoInput(
        dccList: List<CwaCovidCertificate>,
        boosterNotificationRules: JsonNode,
        defaultInputParameters: CclInputParameters,
    ) = DccWalletInfoInput(
        os = defaultInputParameters.os,
        language = defaultInputParameters.language,
        now = SystemTime(
            timestamp = defaultInputParameters.now.timestamp,
            localDate = defaultInputParameters.now.localDate,