"""Unit tests for the pure audio ffmpeg arg builders (no ffmpeg run), plus an
opt-in integration test that actually synthesizes a noise bed when ffmpeg is
present."""

import shutil

import pytest

from tools.pipeline.audio_ops import audio_loop_args, loudnorm_args, white_noise_args


def test_loop_args_mirror_the_video_crossfade_recipe():
    args = audio_loop_args("in.mp3", "out.mp3", duration=30.0, overlap=2.0, ff="FF")
    assert args[0] == "FF"
    joined = " ".join(args)
    # tail crossfades over head, then concats the middle — the audio analogue of
    # crossfade_loop_args. Output length = duration - overlap.
    assert "acrossfade=d=2.0" in joined
    assert "atrim=0:2.0" in joined          # head
    assert "atrim=28.0:30.0" in joined      # tail (d-overlap : d)
    assert "concat=n=2:v=0:a=1" in joined
    assert "-map" in args and "[out]" in args
    assert "-q:a" in args and "4" in args


def test_loop_args_reject_overlap_past_half():
    with pytest.raises(ValueError):
        audio_loop_args("in.mp3", "out.mp3", duration=10.0, overlap=5.0)


def test_loudnorm_args_carry_the_locked_targets():
    args = loudnorm_args("in.mp3", "out.mp3", ff="FF")
    joined = " ".join(args)
    assert "loudnorm=I=-18.0:TP=-1.5:LRA=11.0" in joined
    assert args[0] == "FF" and args[-1] == "out.mp3"


def test_white_noise_args_are_pink_and_clean():
    args = white_noise_args("noise.mp3", duration=60.0, color="pink", ff="FF")
    joined = " ".join(args)
    assert "anoisesrc=color=pink" in joined
    assert "-t" in args and "60.0" in args
    assert args[-1] == "noise.mp3"


def test_white_noise_rejects_unknown_color():
    with pytest.raises(ValueError):
        white_noise_args("noise.mp3", color="ultraviolet")


def _have_ffmpeg() -> bool:
    if shutil.which("ffmpeg"):
        return True
    try:
        import imageio_ffmpeg  # noqa: F401
        return True
    except Exception:
        return False


@pytest.mark.skipif(not _have_ffmpeg(), reason="no ffmpeg available")
def test_generate_white_noise_writes_a_playable_loop(tmp_path):
    from tools.pipeline.audio_run import generate_white_noise
    out = generate_white_noise(tmp_path / "pink.mp3", duration=2.0)
    assert out.exists() and out.stat().st_size > 0
