package dev.privacyllc.period

import android.app.Application
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject

/**
 * The application, and WorkManager's entry point.
 *
 * `Configuration.Provider` replaces WorkManager's default initializer so the
 * reminder worker can be constructed by Hilt with the repository it needs. The
 * default initializer is removed in the manifest — leaving both in place gives
 * you a WorkManager that was already initialised before this ever runs, and a
 * worker that fails to instantiate with a message about a missing no-arg
 * constructor.
 */
@HiltAndroidApp
class PeriodApplication : Application(), Configuration.Provider {

    @Inject lateinit var workerFactory: HiltWorkerFactory

    @Inject lateinit var reminderCoordinator: dev.privacyllc.period.notifications.ReminderCoordinator

    /**
     * Lives as long as the process, because what it watches does.
     *
     * A forecast can move while no screen is open — the engine re-conditions on
     * a "Not yet" recorded from a notification action — and a reminder queued
     * against the old date is wrong from that moment. Tying this to a ViewModel
     * would mean it only ran while somebody was looking.
     */
    private val applicationScope =
        kotlinx.coroutines.CoroutineScope(kotlinx.coroutines.SupervisorJob() + kotlinx.coroutines.Dispatchers.Default)

    override fun onCreate() {
        super.onCreate()
        reminderCoordinator.start(applicationScope)
    }

    override val workManagerConfiguration: Configuration
        get() = Configuration.Builder()
            .setWorkerFactory(workerFactory)
            // Reminders must never write a cycle date to logcat — §45 applies to
            // background work exactly as much as to the UI, and a worker's log
            // is the kind nobody sees in testing.
            .setMinimumLoggingLevel(android.util.Log.WARN)
            .build()
}
