"""Tests for the monotonic marker."""

import textwrap


def test_monotonic_desc_all_implied(pytester):
    """When the highest count passes, all lower counts are implied."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        @pytest.mark.monotonic("count")
        @pytest.mark.parametrize("count", [10, 50, 100],
                                 ids=["c10", "c50", "c100"])
        def test_count(count):
            assert True
    """))
    result = pytester.runpytest("-v")
    result.assert_outcomes(passed=3)
    lines = result.stdout.str()
    assert "c100" in lines
    assert "IMPLIED" in lines


def test_monotonic_desc_failure_bisects(pytester):
    """When the highest fails, the next runs; implied stops at the pass."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        @pytest.mark.monotonic("count")
        @pytest.mark.parametrize("count", [10, 50, 100],
                                 ids=["c10", "c50", "c100"])
        def test_count(count):
            assert count < 100
    """))
    result = pytester.runpytest("-v")
    result.assert_outcomes(passed=2, failed=1)
    lines = result.stdout.str()
    # c100 runs first (desc) and fails
    assert "FAILED" in lines
    # c50 runs (passes) → c10 implied
    assert "IMPLIED" in lines


def test_monotonic_asc(pytester):
    """direction='asc' runs smallest first."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        @pytest.mark.monotonic("count", direction="asc")
        @pytest.mark.parametrize("count", [10, 50, 100],
                                 ids=["c10", "c50", "c100"])
        def test_count(count):
            assert True
    """))
    result = pytester.runpytest("-v")
    result.assert_outcomes(passed=3)
    lines = result.stdout.str()
    assert "IMPLIED" in lines


def test_monotonic_no_imply_flag(pytester):
    """--no-imply disables implication; all tests run."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        results = []

        @pytest.mark.monotonic("count")
        @pytest.mark.parametrize("count", [10, 50, 100],
                                 ids=["c10", "c50", "c100"])
        def test_count(count):
            results.append(count)
            assert True
    """))
    result = pytester.runpytest("-v", "--no-imply")
    result.assert_outcomes(passed=3)
    assert "IMPLIED" not in result.stdout.str()


def test_monotonic_ordering(pytester):
    """Monotonic groups are reordered: highest first for desc."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        order = []

        @pytest.mark.monotonic("n")
        @pytest.mark.parametrize("n", [1, 2, 3], ids=["n1", "n2", "n3"])
        def test_order(n):
            order.append(n)

        def test_check():
            # Only n3 actually runs (n2, n1 are implied)
            assert order == [3]
    """))
    result = pytester.runpytest("-v")
    result.assert_outcomes(passed=4)


def test_monotonic_independent_groups(pytester):
    """Different test functions form independent monotonic groups."""
    pytester.makepyfile(textwrap.dedent("""\
        import pytest

        @pytest.mark.monotonic("n")
        @pytest.mark.parametrize("n", [1, 5], ids=["n1", "n5"])
        def test_alpha(n):
            assert True

        @pytest.mark.monotonic("n")
        @pytest.mark.parametrize("n", [1, 5], ids=["n1", "n5"])
        def test_beta(n):
            assert n < 5   # n5 fails for beta

    """))
    result = pytester.runpytest("-v")
    # alpha: n5 passes → n1 implied (2 passed)
    # beta: n5 fails → n1 runs and passes (1 failed, 1 passed)
    result.assert_outcomes(passed=3, failed=1)
