package wang.yaojia.webterm.terminalview

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test

/**
 * The R5 gate (plan §6.4) — the pure cols×rows resize arithmetic, verified against KNOWN font metrics
 * so it can never drift from the server/web/iOS contract without a device. The real metrics come from
 * Termux's `TerminalRenderer` at runtime; this test pins the formula that turns them into a grid.
 */
class TerminalGridMathTest {

    // 10px-wide cells, 20px line spacing — an easy exact-division case.
    private val fontWidth = 10f
    private val lineSpacing = 20

    @Test
    fun `exact division yields expected grid minus symmetric padding`() {
        // usableW = 820 - 2*10 = 800 → 80 cols; usableH = 500 - 2*10 = 480 → 24 rows.
        val grid = TerminalGridMath.computeGridSize(
            viewWidthPx = 820, viewHeightPx = 500,
            horizontalPaddingPx = 10, verticalPaddingPx = 10,
            fontWidthPx = fontWidth, fontLineSpacingPx = lineSpacing,
        )
        assertEquals(TerminalGridSize(cols = 80, rows = 24), grid)
    }

    @Test
    fun `partial cells floor down`() {
        // usableW = 795 → floor(795/10)=79 cols; usableH = 495 → floor(495/20)=24 rows.
        val grid = TerminalGridMath.computeGridSize(
            viewWidthPx = 795, viewHeightPx = 495,
            horizontalPaddingPx = 0, verticalPaddingPx = 0,
            fontWidthPx = fontWidth, fontLineSpacingPx = lineSpacing,
        )
        assertEquals(TerminalGridSize(cols = 79, rows = 24), grid)
    }

    @Test
    fun `non-positive view dimensions drop to null (pre-layout)`() {
        assertNull(
            TerminalGridMath.computeGridSize(0, 500, 0, 0, fontWidth, lineSpacing),
            "zero width is pre-layout — no grid",
        )
        assertNull(
            TerminalGridMath.computeGridSize(820, 0, 0, 0, fontWidth, lineSpacing),
            "zero height is pre-layout — no grid",
        )
    }

    @Test
    fun `non-positive metrics drop to null`() {
        assertNull(TerminalGridMath.computeGridSize(820, 500, 0, 0, 0f, lineSpacing))
        assertNull(TerminalGridMath.computeGridSize(820, 500, 0, 0, fontWidth, 0))
    }

    @Test
    fun `padding larger than the view drops to null`() {
        assertNull(
            TerminalGridMath.computeGridSize(20, 500, 20, 0, fontWidth, lineSpacing),
            "usable width <= 0 after padding — no grid",
        )
    }

    @Test
    fun `a tiny viewport still clamps to at least 1x1`() {
        val grid = TerminalGridMath.computeGridSize(5, 5, 0, 0, fontWidth, lineSpacing)
        assertEquals(TerminalGridSize(cols = 1, rows = 1), grid)
    }
}
