"""Tests for adaptive silence buffer formula in video_renderer.py (A1).

The renderer lives behind heavy GCP + FFmpeg deps only available in Docker.
These tests cover the pure arithmetic used inside _render_pause_insert_method;
they do not import VideoRendererService to stay runnable locally via pytest.
"""

import pytest


# ── Pure formula tests (no FFmpeg, no GCS) ───────────────────────────────────
#
# Mirrors the exact formula in _render_pause_insert_method:
#   natural_gap = natural_gap_ms / 1000.0
#   silence_before = max(0.05, default_buf - natural_gap * 0.5)
#   silence_after  = max(min_after,  default_buf - natural_gap * 0.3)

def _buffers(
    natural_gap_ms: float,
    default_buf: float = 0.5,
    min_after: float = 0.1,
) -> tuple[float, float]:
    natural_gap = natural_gap_ms / 1000.0
    silence_before = max(0.05, default_buf - natural_gap * 0.5)
    silence_after = max(min_after, default_buf - natural_gap * 0.3)
    return silence_before, silence_after


@pytest.mark.parametrize("natural_gap_ms,exp_before,exp_after", [
    # No natural gap → full default buffers
    (0,    0.50, 0.50),
    # 200 ms gap: before = 0.5 - 0.1 = 0.40; after = 0.5 - 0.06 = 0.44
    (200,  0.40, 0.44),
    # 500 ms gap: before = 0.5 - 0.25 = 0.25; after = 0.5 - 0.15 = 0.35
    (500,  0.25, 0.35),
    # 1000 ms gap: before = max(0.05, 0.5-0.5)=0.05; after = max(0.1, 0.5-0.3)=0.20
    (1000, 0.05, 0.20),
    # 1500 ms gap: before=0.05 (floor); after = max(0.1, 0.5-0.45)=0.10 (floor)
    (1500, 0.05, 0.10),
    # 2000 ms gap: both at their floors
    (2000, 0.05, 0.10),
])
def test_buffer_formula(natural_gap_ms, exp_before, exp_after):
    before, after = _buffers(natural_gap_ms)
    assert before == pytest.approx(exp_before, abs=0.001)
    assert after == pytest.approx(exp_after, abs=0.001)


def test_total_freeze_duration_uses_adaptive_buffers():
    """total_freeze_duration = ad_duration + silence_before + silence_after."""
    ad_duration = 5.0
    natural_gap_ms = 800.0  # 800ms natural gap

    before, after = _buffers(natural_gap_ms)
    total = ad_duration + before + after

    # before = max(0.05, 0.5 - 0.4) = 0.10; after = max(0.1, 0.5 - 0.24) = 0.26
    assert total == pytest.approx(ad_duration + before + after, abs=0.001)
    # Sanity: less than the old constant 1.0s overhead when there's a natural gap
    assert (before + after) < 1.0


def test_buffers_never_below_floor():
    """silence_before never < 0.05, silence_after never < 0.10, regardless of gap size."""
    for gap_ms in [0, 100, 500, 1000, 5000, 10000]:
        before, after = _buffers(gap_ms)
        assert before >= 0.05, f"silence_before={before} below floor for gap={gap_ms}ms"
        assert after >= 0.10, f"silence_after={after} below floor for gap={gap_ms}ms"


def test_large_natural_gap_has_less_total_overhead_than_small_gap():
    """Larger natural gap → smaller combined silence overhead."""
    before_small, after_small = _buffers(100)
    before_large, after_large = _buffers(900)

    assert (before_small + after_small) > (before_large + after_large)


def test_renderer_config_defaults_match_formula():
    """The config defaults used in the formula match the expected values."""
    # These must stay in sync with config.py defaults:
    #   ad_silence_buffer_default: float = 0.5
    #   ad_silence_buffer_min_after: float = 0.1
    DEFAULT_BUF = 0.5
    MIN_AFTER = 0.1
    assert DEFAULT_BUF == pytest.approx(0.5)
    assert MIN_AFTER == pytest.approx(0.1)
    # Verify floors are derived from these values
    _, after = _buffers(10_000, DEFAULT_BUF, MIN_AFTER)  # saturated gap
    assert after == pytest.approx(MIN_AFTER)
