<commit_before>package info.nightscout.androidaps.utils.stats

import android.text.Spanned
import android.util.LongSparseArray
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TotalDailyDose
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.toText
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject

class TddCalculator @Inject constructor(
    private val aapsLogger: AAPSLogger,
    private val rh: ResourceHelper,
    private val activePlugin: ActivePlugin,
    private val profileFunction: ProfileFunction,
    private val dateUtil: DateUtil,
    private val iobCobCalculator: IobCobCalculator,
    private val repository: AppRepository
) {

    fun calculate(days: Long): LongSparseArray<TotalDailyDose> {
        val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs())
        val endTime = MidnightTime.calc(dateUtil.now())

        val result = LongSparseArray<TotalDailyDose>()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                val midnight = MidnightTime.calc(t.timestamp)
                val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            val midnight = MidnightTime.calc(t.timestamp)
            val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            result.put(midnight, tdd)
        }

        val calculationStep = T.mins(5).msecs()
        val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
        for (t in startTime until endTime step calculationStep) {
            val midnight = MidnightTime.calc(t)
            val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = tempBasals[t]
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()
            }
            result.put(midnight, tdd)
        }
        for (i in 0 until result.size()) {
            val tdd = result.valueAt(i)
            tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        }
        aapsLogger.debug(LTag.CORE, result.toString())
        return result
    }

    fun calculateDaily():TotalDailyDose {
        val  startTime = MidnightTime.calc(dateUtil.now() )
        val endTime = dateUtil.now()
        val tdd = TotalDailyDose(timestamp = startTime)
        //val result = TotalDailyDose()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                //val midnight = MidnightTime.calc(t.timestamp)
                //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                //result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            //val midnight = MidnightTime.calc(t.timestamp)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            //result.put(midnight, tdd)
        }
        val calculationStep = T.mins(5).msecs()
        for (t in startTime until endTime step calculationStep) {

            //val midnight = MidnightTime.calc(t)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / T.mins(5).msecs().toDouble() * calculationStep.toDouble()

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / T.mins(5).msecs().toDouble() * calculationStep.toDouble()
            }
            //result.put(midnight, tdd)
        }
        //for (i in 0 until tdd.size()) {
        //val tdd = result.valueAt(i)
        tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        //}


        aapsLogger.debug(LTag.CORE, tdd.toString())
        return tdd
    }
    fun calculate24Daily():TotalDailyDose {
        val  startTime = dateUtil.now() - T.hours(hour = 24).msecs()
        val endTime = dateUtil.now()
        val tdd = TotalDailyDose(timestamp = startTime)
        //val result = TotalDailyDose()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                //val midnight = MidnightTime.calc(t.timestamp)
                //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                //result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            //val midnight = MidnightTime.calc(t.timestamp)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            //result.put(midnight, tdd)
        }
        val calculationStep = T.mins(5).msecs()
        val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
        for (t in startTime until endTime step calculationStep) {

            //val midnight = MidnightTime.calc(t)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / T.mins(5).msecs().toDouble() * calculationStep.toDouble()

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / T.mins(5).msecs().toDouble() * calculationStep.toDouble()
            }
            //result.put(midnight, tdd)
        }
        //for (i in 0 until tdd.size()) {
        //val tdd = result.valueAt(i)
        tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        //}


        aapsLogger.debug(LTag.CORE, tdd.toString())
        return tdd
    }
    fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
        val totalTdd = TotalDailyDose(timestamp = dateUtil.now())
        for (i in 0 until tdds.size()) {
            val tdd = tdds.valueAt(i)
            totalTdd.basalAmount += tdd.basalAmount
            totalTdd.bolusAmount += tdd.bolusAmount
            totalTdd.totalAmount += tdd.totalAmount
            totalTdd.carbs += tdd.carbs
        }
        totalTdd.basalAmount /= tdds.size().toDouble()
        totalTdd.bolusAmount /= tdds.size().toDouble()
        totalTdd.totalAmount /= tdds.size().toDouble()
        totalTdd.carbs /= tdds.size().toDouble()
        return totalTdd
    }

    fun stats(): Spanned {
        val tdds = calculate(7)
        val averageTdd = averageTDD(tdds)<commit_msg>Use of calculation step reverted back to value / 60 * 5, as calculation step method was producing incorrect, very large numbers.<commit_after>package info.nightscout.androidaps.utils.stats

import android.text.Spanned
import android.util.LongSparseArray
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TotalDailyDose
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.toText
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject

class TddCalculator @Inject constructor(
    private val aapsLogger: AAPSLogger,
    private val rh: ResourceHelper,
    private val activePlugin: ActivePlugin,
    private val profileFunction: ProfileFunction,
    private val dateUtil: DateUtil,
    private val iobCobCalculator: IobCobCalculator,
    private val repository: AppRepository
) {

    fun calculate(days: Long): LongSparseArray<TotalDailyDose> {
        val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs())
        val endTime = MidnightTime.calc(dateUtil.now())

        val result = LongSparseArray<TotalDailyDose>()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                val midnight = MidnightTime.calc(t.timestamp)
                val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            val midnight = MidnightTime.calc(t.timestamp)
            val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            result.put(midnight, tdd)
        }

        val calculationStep = T.mins(5).msecs()
        val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
        for (t in startTime until endTime step calculationStep) {
            val midnight = MidnightTime.calc(t)
            val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = tempBasals[t]
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()
            }
            result.put(midnight, tdd)
        }
        for (i in 0 until result.size()) {
            val tdd = result.valueAt(i)
            tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        }
        aapsLogger.debug(LTag.CORE, result.toString())
        return result
    }

    fun calculateDaily():TotalDailyDose {
        val  startTime = MidnightTime.calc(dateUtil.now() )
        val endTime = dateUtil.now()
        val tdd = TotalDailyDose(timestamp = startTime)
        //val result = TotalDailyDose()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                //val midnight = MidnightTime.calc(t.timestamp)
                //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                //result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            //val midnight = MidnightTime.calc(t.timestamp)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            //result.put(midnight, tdd)
        }
        val calculationStep = T.mins(5).msecs()
        for (t in startTime until endTime step calculationStep) {

            //val midnight = MidnightTime.calc(t)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / 60.0 * 5.0

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
            }
            //result.put(midnight, tdd)
        }
        //for (i in 0 until tdd.size()) {
        //val tdd = result.valueAt(i)
        tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        //}


        aapsLogger.debug(LTag.CORE, tdd.toString())
        return tdd
    }
    fun calculate24Daily():TotalDailyDose {
        val  startTime = dateUtil.now() - T.hours(hour = 24).msecs()
        val endTime = dateUtil.now()
        val tdd = TotalDailyDose(timestamp = startTime)
        //val result = TotalDailyDose()
        repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
            .filter { it.type != Bolus.Type.PRIMING }
            .forEach { t ->
                //val midnight = MidnightTime.calc(t.timestamp)
                //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
                tdd.bolusAmount += t.amount
                //result.put(midnight, tdd)
            }
        repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
            //val midnight = MidnightTime.calc(t.timestamp)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            tdd.carbs += t.amount
            //result.put(midnight, tdd)
        }
        val calculationStep = T.mins(5).msecs()
        val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
        for (t in startTime until endTime step calculationStep) {

            //val midnight = MidnightTime.calc(t)
            //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
            val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
            val profile = profileFunction.getProfile(t) ?: continue
            val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
            tdd.basalAmount += absoluteRate / 60.0 * 5.0

            if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
                // they are not included in TBRs
                val eb = iobCobCalculator.getExtendedBolus(t)
                val absoluteEbRate = eb?.rate ?: 0.0
                tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
            }
            //result.put(midnight, tdd)
        }
        //for (i in 0 until tdd.size()) {
        //val tdd = result.valueAt(i)
        tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
        //}


        aapsLogger.debug(LTag.CORE, tdd.toString())
        return tdd
    }
    fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
        val totalTdd = TotalDailyDose(timestamp = dateUtil.now())
        for (i in 0 until tdds.size()) {
            val tdd = tdds.valueAt(i)
            totalTdd.basalAmount += tdd.basalAmount
            totalTdd.bolusAmount += tdd.bolusAmount
            totalTdd.totalAmount += tdd.totalAmount
            totalTdd.carbs += tdd.carbs
        }
        totalTdd.basalAmount /= tdds.size().toDouble()
        totalTdd.bolusAmount /= tdds.size().toDouble()
        totalTdd.totalAmount /= tdds.size().toDouble()
        totalTdd.carbs /= tdds.size().toDouble()
        return totalTdd
    }

    fun stats(): Spanned {
        val tdds = calculate(7)
        val averageTdd = averageTDD(tdds)
{'fraction_non_alphanumeric': 0.10164515592976237, 'fraction_numerical': 0.003932864343876364, 'mean_word_length': 2.4506880733944953, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1090687', 'n_tokens_mistral': 5574, 'n_tokens_neox': 5325, 'n_words': 1010}