from __future__ import annotations

import numpy as np
import pyloudnorm as pyln

from engine.true_peak import measure_true_peak_db, normalize_lufs_true_peak


def _stress_signal(sr=44100, seconds=4.0):
    t = np.arange(int(sr * seconds), dtype=np.float64) / sr
    # High-frequency components with non-grid phases create inter-sample peaks.
    left = 0.72 * np.sin(2 * np.pi * 997 * t + 0.37) + 0.18 * np.sin(2 * np.pi * 15137 * t + 1.11)
    right = 0.70 * np.sin(2 * np.pi * 1009 * t + 0.81) + 0.19 * np.sin(2 * np.pi * 14731 * t + 0.29)
    return np.column_stack((left, right)).astype(np.float64), sr


def test_true_peak_normalizer_holds_ceiling_and_loudness():
    audio, sr = _stress_signal()
    out = normalize_lufs_true_peak(audio, sr, target_lufs=-10.0, ceiling_dbtp=-1.0)
    tp = measure_true_peak_db(out, sr)
    lufs = pyln.Meter(sr).integrated_loudness(out)
    assert tp <= -0.99
    assert abs(lufs - (-10.0)) <= 1.0
    assert np.all(np.isfinite(out))


def test_true_peak_measurement_catches_inter_sample_peak():
    audio, sr = _stress_signal(seconds=1.0)
    sample_peak = 20 * np.log10(np.max(np.abs(audio)) + 1e-12)
    true_peak = measure_true_peak_db(audio, sr)
    assert true_peak >= sample_peak - 1e-6
