"""Tests for start_stop and cut_items_to_window from pyos/printers/printers.py."""

import pytest

from pyos.printers.printers import start_stop, cut_items_to_window


# ===========================================================================
# start_stop
# ===========================================================================

class TestStartStop:
    """Core scrolling window calculation."""

    def test_centered(self):
        """Index in the middle → window centered on it."""
        s, e = start_stop(5, 5, 20)
        assert s <= 5 < e
        assert e - s == 5

    def test_topped_out(self):
        """Index near the start → window starts at 0."""
        s, e = start_stop(1, 5, 20)
        assert s == 0
        assert e == 5

    def test_bottomed_out(self):
        """Index near the end → window ends at list_size."""
        s, e = start_stop(18, 5, 20)
        assert e == 20
        assert s == 15

    def test_window_size_zero(self):
        s, e = start_stop(3, 0, 10)
        assert s <= e
        assert e - s == 0

    def test_window_size_one(self):
        s, e = start_stop(5, 1, 10)
        assert e - s == 1

    def test_list_size_zero(self):
        s, e = start_stop(0, 5, 0)
        assert s == 0
        assert e == 0

    def test_even_window_size(self):
        s, e = start_stop(10, 6, 20)
        assert s <= 10 < e
        assert e - s == 6

    def test_odd_window_size(self):
        s, e = start_stop(10, 7, 20)
        assert s <= 10 < e
        assert e - s == 7

    def test_index_at_zero(self):
        s, e = start_stop(0, 5, 20)
        assert s == 0
        assert e == 5

    def test_index_at_last(self):
        s, e = start_stop(19, 5, 20)
        assert e == 20
        assert s == 15

    def test_index_negative(self):
        """Negative index — should not crash."""
        s, e = start_stop(-1, 5, 10)
        assert s == 0  # topped out
        assert e <= 10

    def test_index_beyond_list_size(self):
        """Index beyond list — should not crash."""
        s, e = start_stop(100, 5, 10)
        assert s >= 0
        assert e <= 10

    def test_window_larger_than_list(self):
        s, e = start_stop(2, 20, 5)
        assert s == 0
        assert e == 5


# ===========================================================================
# cut_items_to_window
# ===========================================================================

class TestCutItemsToWindow:
    def test_returns_correct_slice(self):
        items = list(range(20))
        start, stop, visible = cut_items_to_window(5, items, 5)
        visible_list = list(visible)
        assert len(visible_list) == stop - start
        # The selected index 5 should be in the visible range
        assert start <= 5 < stop

    def test_empty_items(self):
        start, stop, visible = cut_items_to_window(0, [], 5)
        assert list(visible) == []

    def test_window_size_zero(self):
        start, stop, visible = cut_items_to_window(0, [1, 2, 3], 0)
        assert list(visible) == []
