package com.ponzischeme89.memby.benchmark

import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.FrameTimingMetric
import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.benchmark.macro.StartupMode
import androidx.benchmark.macro.StartupTimingMetric
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class HomeBenchmark {
    @get:Rule val benchmarkRule = MacrobenchmarkRule()

    /**
     * The baseline for comparison: no ahead-of-time compilation at all. Keep this around
     * — the only way to know whether [coldStartToHomeWithProfile] is earning its keep is
     * to see the two numbers side by side.
     */
    @Test
    fun coldStartToHomeNoCompilation() = measureColdStart(CompilationMode.None())

    /** What a viewer installing a release APK actually gets. */
    @Test
    fun coldStartToHomeWithProfile() = measureColdStart(CompilationMode.Partial())

    private fun measureColdStart(mode: CompilationMode) = benchmarkRule.measureRepeated(
        packageName = PACKAGE_NAME,
        metrics = listOf(StartupTimingMetric()),
        compilationMode = mode,
        startupMode = StartupMode.COLD,
        iterations = 5,
        setupBlock = { pressHome() },
        measureBlock = { startActivityAndWait() },
    )

    @Test
    fun homeDpadAndRows() = benchmarkRule.measureRepeated(
        packageName = PACKAGE_NAME,
        metrics = listOf(FrameTimingMetric()),
        compilationMode = CompilationMode.Partial(),
        startupMode = StartupMode.WARM,
        iterations = 5,
        setupBlock = { startActivityAndWait() },
        measureBlock = { exerciseHome() },
    )

    private fun MacrobenchmarkScope.exerciseHome() {
        device.pressKeyCode(android.view.KeyEvent.KEYCODE_DPAD_RIGHT)
        device.pressKeyCode(android.view.KeyEvent.KEYCODE_DPAD_RIGHT)
        device.pressKeyCode(android.view.KeyEvent.KEYCODE_DPAD_DOWN)
        device.pressKeyCode(android.view.KeyEvent.KEYCODE_DPAD_RIGHT)
        device.waitForIdle()
    }

    private companion object {
        const val PACKAGE_NAME = "com.ponzischeme89.memby"
    }
}
