package com.ponzischeme89.memby.data

/**
 * Local-day arithmetic, shared by everything that has to answer "what day is it here?".
 *
 * It lived in `HomeMovieHero` while the daily hero rotation was the only caller; the series
 * pace estimate counts in local days for the same reason and must not carry a second copy.
 */

internal const val DAY_MS = 24L * 60L * 60L * 1000L

/**
 * The day the television is living in, counted in local days since the epoch.
 *
 * Local rather than UTC, because "resets at midnight" means the viewer's midnight and not
 * Greenwich's. The zone offset is a parameter rather than something read in here so the
 * arithmetic stays pure and a test can put itself either side of the date line.
 */
internal fun localEpochDay(nowMs: Long, zoneOffsetMs: Int): Long =
    floorDiv(nowMs + zoneOffsetMs, DAY_MS)

/**
 * How long until the local day rolls over. Never zero and never negative: this drives a
 * timer, and a zero would spin it. Exactly at midnight the answer is a whole day, because
 * the day that has just begun is not the one being waited for.
 */
internal fun millisUntilNextLocalDay(nowMs: Long, zoneOffsetMs: Int): Long {
    val local = nowMs + zoneOffsetMs
    return DAY_MS - (local - floorDiv(local, DAY_MS) * DAY_MS)
}

// Math.floorDiv/floorMod for longs arrived in API 24 and this app still ships to 23, so
// the two lines they would have saved are written out instead.
internal fun floorDiv(value: Long, divisor: Long): Long {
    val quotient = value / divisor
    return if (value % divisor != 0L && (value xor divisor) < 0L) quotient - 1L else quotient
}

internal fun floorMod(value: Long, divisor: Long): Long =
    value - floorDiv(value, divisor) * divisor
