from __future__ import annotations

import gc
import os
import time
from datetime import datetime
from unittest.mock import Mock

import pytest
from inference.core.workflows.core_steps.analytics.detection_event_log.v1 import \
    DetectionEventLogBlockV1
from inference.core.workflows.execution_engine.entities.base import \
    VideoMetadata


def codeflash_wrap(codeflash_wrapped, codeflash_test_module_name, codeflash_test_class_name, codeflash_test_name, codeflash_function_name, codeflash_line_id, codeflash_loop_index, *args, **kwargs):
    test_id = f'{codeflash_test_module_name}:{codeflash_test_class_name}:{codeflash_test_name}:{codeflash_line_id}:{codeflash_loop_index}'
    if not hasattr(codeflash_wrap, 'index'):
        codeflash_wrap.index = {}
    if test_id in codeflash_wrap.index:
        codeflash_wrap.index[test_id] += 1
    else:
        codeflash_wrap.index[test_id] = 0
    codeflash_test_index = codeflash_wrap.index[test_id]
    invocation_id = f'{codeflash_line_id}_{codeflash_test_index}'
    test_stdout_tag = f"{codeflash_test_module_name}:{(codeflash_test_class_name + '.' if codeflash_test_class_name else '')}{codeflash_test_name}:{codeflash_function_name}:{codeflash_loop_index}:{invocation_id}"
    print(f'!$######{test_stdout_tag}######$!')
    exception = None
    gc.disable()
    try:
        counter = time.perf_counter_ns()
        return_value = codeflash_wrapped(*args, **kwargs)
        codeflash_duration = time.perf_counter_ns() - counter
    except Exception as e:
        codeflash_duration = time.perf_counter_ns() - counter
        exception = e
    gc.enable()
    print(f'!######{test_stdout_tag}:{codeflash_duration}######!')
    if exception:
        raise exception
    return return_value

@pytest.fixture
def block():
    """Create a fresh DetectionEventLogBlockV1 instance for each test."""
    return DetectionEventLogBlockV1()

@pytest.fixture
def video_metadata_with_fps():
    """Create VideoMetadata with fps and no frame_timestamp."""
    metadata = Mock(spec=VideoMetadata)
    metadata.fps = 30.0
    metadata.frame_timestamp = None
    return metadata

@pytest.fixture
def video_metadata_with_timestamp():
    """Create VideoMetadata with frame_timestamp."""
    metadata = Mock(spec=VideoMetadata)
    metadata.fps = 30.0
    dt = datetime(2024, 1, 1, 12, 0, 0)
    metadata.frame_timestamp = dt
    return metadata

def test_get_relative_time_fallback_fps_first_frame(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation using fallback FPS for first frame (current_frame=1).'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fallback_fps_first_frame', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_fallback_fps_second_frame(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation for second frame using fallback FPS.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fallback_fps_second_frame', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=2, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_fallback_fps_30th_frame(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation at frame 30 with 30 FPS.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fallback_fps_30th_frame', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=30, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_different_fps_60fps(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation with different FPS value.'
    video_metadata_with_fps.fps = 60.0
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_different_fps_60fps', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=61, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_uses_metadata_fps_over_fallback(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that metadata.fps is used when available, not fallback_fps.'
    video_metadata_with_fps.fps = 24.0
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_uses_metadata_fps_over_fallback', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=25, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_with_frame_timestamp(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation using frame_timestamp when available.'
    dt = datetime(2024, 1, 1, 12, 0, 5)
    video_metadata_with_timestamp.frame_timestamp = dt
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_with_frame_timestamp', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_frame_timestamp_second_call(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test frame_timestamp calculation across multiple calls.'
    dt1 = datetime(2024, 1, 1, 12, 0, 5)
    video_metadata_with_timestamp.frame_timestamp = dt1
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_frame_timestamp_second_call', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result1 = codeflash_output
    dt2 = datetime(2024, 1, 1, 12, 0, 10)
    video_metadata_with_timestamp.frame_timestamp = dt2
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_frame_timestamp_second_call', '_get_relative_time', '7', codeflash_loop_index, video_id='video_1', current_frame=150, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result2 = codeflash_output

def test_get_relative_time_multiple_videos_independent(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that different videos maintain independent first_frame_timestamps.'
    dt1 = datetime(2024, 1, 1, 12, 0, 5)
    video_metadata_with_timestamp.frame_timestamp = dt1
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_multiple_videos_independent', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result1 = codeflash_output
    dt2 = datetime(2024, 1, 1, 12, 0, 15)
    video_metadata_with_timestamp.frame_timestamp = dt2
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_multiple_videos_independent', '_get_relative_time', '7', codeflash_loop_index, video_id='video_2', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result2 = codeflash_output

def test_get_relative_time_metadata_fps_is_zero(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that fallback_fps is used when metadata.fps is 0.'
    video_metadata_with_fps.fps = 0
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_metadata_fps_is_zero', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_metadata_fps_is_none(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that fallback_fps is used when metadata.fps is None.'
    video_metadata_with_fps.fps = None
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_metadata_fps_is_none', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_very_small_fps(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation with very small FPS value.'
    video_metadata_with_fps.fps = 0.5
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_very_small_fps', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=3, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_very_high_fps(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation with very high FPS value.'
    video_metadata_with_fps.fps = 240.0
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_very_high_fps', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=241, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_large_frame_number(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation with very large frame number.'
    video_metadata_with_fps.fps = 30.0
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_large_frame_number', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=108001, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_fractional_fps(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test relative time calculation with fractional FPS.'
    video_metadata_with_fps.fps = 29.97
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fractional_fps', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=30, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output
    expected = 29.0 / 29.97

def test_get_relative_time_timestamp_same_second(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test frame_timestamp with events in the same second.'
    dt = datetime(2024, 1, 1, 12, 0, 5, 123456)
    video_metadata_with_timestamp.frame_timestamp = dt
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_timestamp_same_second', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_timestamp_microseconds(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test frame_timestamp precision with microseconds.'
    dt1 = datetime(2024, 1, 1, 12, 0, 5, 0)
    video_metadata_with_timestamp.frame_timestamp = dt1
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_timestamp_microseconds', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result1 = codeflash_output
    dt2 = datetime(2024, 1, 1, 12, 0, 5, 33333)
    video_metadata_with_timestamp.frame_timestamp = dt2
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_timestamp_microseconds', '_get_relative_time', '7', codeflash_loop_index, video_id='video_1', current_frame=2, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result2 = codeflash_output

def test_get_relative_time_empty_video_id(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with empty string video_id.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_empty_video_id', '_get_relative_time', '1', codeflash_loop_index, video_id='', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_special_video_id(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with special characters in video_id.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_special_video_id', '_get_relative_time', '1', codeflash_loop_index, video_id='video_!@#$%^&*()', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_unicode_video_id(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with unicode characters in video_id.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_unicode_video_id', '_get_relative_time', '1', codeflash_loop_index, video_id='видео_1', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_fallback_fps_zero_raises_error(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that division by zero occurs when both fps and fallback_fps are 0.'
    video_metadata_with_fps.fps = 0
    with pytest.raises(ZeroDivisionError):
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fallback_fps_zero_raises_error', '_get_relative_time', '2_0', codeflash_loop_index, video_id='video_1', current_frame=31, metadata=video_metadata_with_fps, fallback_fps=0.0)

def test_get_relative_time_fallback_fps_very_small(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with very small but non-zero fallback_fps.'
    video_metadata_with_fps.fps = None
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_fallback_fps_very_small', '_get_relative_time', '2', codeflash_loop_index, video_id='video_1', current_frame=2, metadata=video_metadata_with_fps, fallback_fps=0.001)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_current_frame_is_1(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test that frame 1 always gives relative time of 0.'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_current_frame_is_1', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_fps, fallback_fps=25.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_current_frame_is_negative(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with negative frame number (edge case).'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_current_frame_is_negative', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=-5, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_current_frame_is_zero(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test with zero frame number (edge case).'
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_current_frame_is_zero', '_get_relative_time', '1', codeflash_loop_index, video_id='video_1', current_frame=0, metadata=video_metadata_with_fps, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_get_relative_time_many_videos_with_timestamps(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test handling of many different videos with frame_timestamp.'
    for i in range(1000):
        dt = datetime(2024, 1, 1, 12, 0, 5 + i)
        video_metadata_with_timestamp.frame_timestamp = dt
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_many_videos_with_timestamps', '_get_relative_time', '1_2', codeflash_loop_index, video_id=f'video_{i}', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output

def test_get_relative_time_sequential_frames_same_video(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test sequential frame processing for a single video.'
    video_metadata_with_fps.fps = 30.0
    for frame_num in range(1, 1001):
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_sequential_frames_same_video', '_get_relative_time', '2_0', codeflash_loop_index, video_id='video_1', current_frame=frame_num, metadata=video_metadata_with_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
        expected = (frame_num - 1) / 30.0

def test_get_relative_time_many_videos_fallback_fps(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test handling of many videos using fallback FPS.'
    video_metadata_with_fps.fps = 30.0
    for i in range(1000):
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_many_videos_fallback_fps', '_get_relative_time', '2_0', codeflash_loop_index, video_id=f'video_{i}', current_frame=100, metadata=video_metadata_with_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
        expected = 99.0 / 30.0

def test_get_relative_time_varying_fps_across_videos(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test varying FPS values across different videos.'
    fps_values = [10, 15, 20, 24, 25, 29.97, 30, 50, 60, 120]
    frame_num = 100
    for i in range(100):
        fps = fps_values[i % len(fps_values)]
        video_metadata_with_fps.fps = fps
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_varying_fps_across_videos', '_get_relative_time', '3_2', codeflash_loop_index, video_id=f'video_{i}', current_frame=frame_num, metadata=video_metadata_with_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
        expected = (frame_num - 1) / fps

def test_get_relative_time_large_frame_numbers_performance(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test performance with very large frame numbers.'
    video_metadata_with_fps.fps = 30.0
    large_frames = [1000000, 5000000, 10000000]
    for frame_num in large_frames:
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_large_frame_numbers_performance', '_get_relative_time', '3_0', codeflash_loop_index, video_id='video_1', current_frame=frame_num, metadata=video_metadata_with_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
        expected = (frame_num - 1) / 30.0

def test_get_relative_time_timestamp_large_time_span(block, video_metadata_with_timestamp):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test frame_timestamp with large time spans (many seconds apart).'
    dt1 = datetime(2024, 1, 1, 12, 0, 0)
    video_metadata_with_timestamp.frame_timestamp = dt1
    codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_timestamp_large_time_span', '_get_relative_time', '3', codeflash_loop_index, video_id='video_1', current_frame=1, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
    codeflash_output = codeflash_return_value
    result1 = codeflash_output
    for i in range(1, 101):
        dt = datetime(2024, 1, 1, 12, i // 12, i % 60)
        video_metadata_with_timestamp.frame_timestamp = dt
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_timestamp_large_time_span', '_get_relative_time', '5_2', codeflash_loop_index, video_id='video_1', current_frame=i, metadata=video_metadata_with_timestamp, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
        if i > 1:
            pass

def test_get_relative_time_interleaved_videos(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test interleaved processing of multiple videos.'
    video_metadata_with_fps.fps = 30.0
    for frame in range(1, 101):
        for video_idx in range(10):
            codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_interleaved_videos', '_get_relative_time', '2_0_0', codeflash_loop_index, video_id=f'video_{video_idx}', current_frame=frame, metadata=video_metadata_with_fps, fallback_fps=30.0)
            codeflash_output = codeflash_return_value
            result = codeflash_output
            expected = (frame - 1) / 30.0

def test_get_relative_time_mixed_fps_and_timestamp(block):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test mixed usage: some videos with FPS, some with timestamp.'
    metadata_fps = Mock(spec=VideoMetadata)
    metadata_fps.fps = 30.0
    metadata_fps.frame_timestamp = None
    metadata_ts = Mock(spec=VideoMetadata)
    metadata_ts.fps = 30.0
    metadata_ts.frame_timestamp = datetime(2024, 1, 1, 12, 0, 5)
    for i in range(50):
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_mixed_fps_and_timestamp', '_get_relative_time', '7_0', codeflash_loop_index, video_id=f'video_fps_{i}', current_frame=100, metadata=metadata_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output
    for i in range(50):
        metadata_ts.frame_timestamp = datetime(2024, 1, 1, 12, 0, 5 + i)
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_mixed_fps_and_timestamp', '_get_relative_time', '8_1', codeflash_loop_index, video_id=f'video_ts_{i}', current_frame=1, metadata=metadata_ts, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output

def test_get_relative_time_repeated_calls_same_video(block, video_metadata_with_fps):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    'Test repeated calls for the same video and frame.'
    video_metadata_with_fps.fps = 30.0
    for _ in range(1000):
        codeflash_return_value = codeflash_wrap(block._get_relative_time, 'tests.inference.unit_tests.test__get_relative_time__unit_test_1', None, 'test_get_relative_time_repeated_calls_same_video', '_get_relative_time', '2_0', codeflash_loop_index, video_id='video_1', current_frame=100, metadata=video_metadata_with_fps, fallback_fps=30.0)
        codeflash_output = codeflash_return_value
        result = codeflash_output