"""Step definitions for test_infra_flaky_test_example feature.

These steps complement the existing async_execution_steps.py definitions
and add the time-bounded heartbeat step that validates the busy-wait fix
for the flaky ``test_example_flaky_test`` detection (issue #1542).
"""

from __future__ import annotations

import time
from datetime import UTC, datetime

from behave import when
from behave.runner import Context


@when("I record a heartbeat on the async job within {seconds:d} seconds")
def step_record_heartbeat_bounded(context: Context, seconds: int) -> None:
    """Record a heartbeat using the busy-wait guard, bounded by a wall-clock limit.

    This step validates that the busy-wait loop in the heartbeat step
    terminates within a reasonable time budget, ensuring the fix for the
    flaky ``test_example_flaky_test`` does not introduce an infinite hang.
    """
    before = context.async_job.last_heartbeat
    deadline = time.monotonic() + seconds

    # Busy-wait until the clock advances past the previous heartbeat.
    # This is the same guard used in step_record_heartbeat; the bounded
    # variant adds an explicit deadline assertion so CI catches hangs.
    while datetime.now(UTC) <= before:
        if time.monotonic() > deadline:
            raise AssertionError(
                f"Clock did not advance past previous heartbeat within {seconds}s. "
                "This indicates a system clock issue, not a test bug."
            )
        time.sleep(0.001)

    context.async_job.record_heartbeat()
    context.heartbeat_before = before
