package com.ponzischeme89.memby.benchmark

import android.view.KeyEvent
import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * Records the classes and methods the launcher touches between process start and the
 * first few D-pad moves, so ART can compile them ahead of time instead of interpreting
 * them on a TV box that has nothing to spare.
 *
 * Run against a real television:
 *
 *     .\gradlew.bat :app:generateReleaseBaselineProfile
 *
 * The output lands in app/src/release/generated/baselineProfiles and is checked in, so
 * an ordinary `assembleRelease` needs no device. Regenerate it after a change that moves
 * the startup path — a stale profile is not harmful, just progressively less useful.
 */
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
    @get:Rule val rule = BaselineProfileRule()

    @Test
    fun startupAndBrowse() = rule.collect(
        packageName = "com.ponzischeme89.memby",
        // The signed-in launcher renders from HomeCache before the network answers, so a
        // cold start reaches real rows without waiting on the gateway. Include enough
        // D-pad movement to pull in the row/card composables and Coil's decode path,
        // which is where the first-scroll jank lives.
        includeInStartupProfile = true,
    ) {
        pressHome()
        startActivityAndWait()
        browseHome()
    }

    private fun MacrobenchmarkScope.browseHome() {
        repeat(4) { device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) }
        device.waitForIdle()
        device.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN)
        repeat(3) { device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) }
        device.waitForIdle()
        device.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN)
        device.waitForIdle()
    }
}
