"""Thin runner: probe duration, then run the audio production pass (seamless
loop -> loudness normalize) and synthesize the white-noise bed. The pure arg
builders (tools.pipeline.audio_ops) are unit-tested; this glue is covered by the
opt-in integration test."""

from __future__ import annotations

import re
import subprocess
from pathlib import Path

from .audio_ops import audio_loop_args, loudnorm_args, white_noise_args
from .run import resolve_ffmpeg


def _probe_audio_duration(src, ff: str) -> float:
    """Audio length in seconds via ffmpeg (no system ffprobe): decode to null and
    read the last reported time off stderr."""
    proc = subprocess.run(
        [ff, "-i", str(src), "-f", "null", "-"],
        capture_output=True, text=True,
    )
    times = re.findall(r"time=(\d+):(\d+):(\d+\.\d+)", proc.stderr)
    if not times:
        raise ValueError(f"could not probe audio duration of {src}")
    h, m, s = times[-1]
    return int(h) * 3600 + int(m) * 60 + float(s)


def _run(args: list[str]) -> None:
    subprocess.run(args, check=True, capture_output=True)


def process_soundtrack(src, dst, *, overlap: float = 2.0, ff: str | None = None) -> Path:
    """Produce a seamless, loudness-normalized loop from a sourced ambience clip.
    Clips too short to crossfade-loop (<= 2*overlap) are normalized only."""
    ff = ff or resolve_ffmpeg()
    src, dst = Path(src), Path(dst)
    dst.parent.mkdir(parents=True, exist_ok=True)
    duration = _probe_audio_duration(src, ff)
    tmp = dst.with_suffix(".loop.tmp.mp3")
    if duration > 2 * overlap + 0.5:
        _run(audio_loop_args(src, tmp, duration=duration, overlap=overlap, ff=ff))
        _run(loudnorm_args(tmp, dst, ff=ff))
        tmp.unlink(missing_ok=True)
    else:
        _run(loudnorm_args(src, dst, ff=ff))
    return dst


def generate_white_noise(dst, *, duration: float = 60.0, color: str = "pink",
                         ff: str | None = None) -> Path:
    """Synthesize + normalize the global white-noise bed."""
    ff = ff or resolve_ffmpeg()
    dst = Path(dst)
    dst.parent.mkdir(parents=True, exist_ok=True)
    tmp = dst.with_suffix(".raw.tmp.mp3")
    _run(white_noise_args(tmp, duration=duration, color=color, ff=ff))
    _run(loudnorm_args(tmp, dst, ff=ff))
    tmp.unlink(missing_ok=True)
    return dst
