"""Tests for core/audio_io.py"""

import numpy as np
import tempfile
from pathlib import Path

from mlx_music.core.audio_io import (
    duration_to_samples,
    load_wav,
    normalize_stereo_48k,
    samples_to_duration,
    save_wav,
)


class TestDurationConversions:
    def test_duration_to_samples(self):
        assert duration_to_samples(1.0) == 48000
        assert duration_to_samples(0.5) == 24000
        assert duration_to_samples(30.0) == 1_440_000

    def test_samples_to_duration(self):
        assert samples_to_duration(48000) == 1.0
        assert samples_to_duration(1_440_000) == 30.0


class TestSaveLoadWav:
    def test_roundtrip_stereo(self):
        """Save stereo audio, load it back, verify shape and values."""
        audio = np.random.randn(48000, 2).astype(np.float32) * 0.5
        with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
            path = f.name
        save_wav(audio, path, normalize=False)
        loaded, sr = load_wav(path)
        assert sr == 48000
        assert loaded.shape == (48000, 2)
        # Values should be close (WAV encoding may lose precision)
        assert np.allclose(audio, loaded, atol=1e-4)

    def test_mono_to_stereo(self):
        """Loading mono should auto-convert to stereo."""
        import soundfile as sf

        mono = np.random.randn(24000).astype(np.float32) * 0.5
        with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
            path = f.name
        sf.write(path, mono, 48000)
        loaded, sr = load_wav(path)
        assert loaded.shape[1] == 2
        # Both channels should be identical (duplicated mono)
        assert np.allclose(loaded[:, 0], loaded[:, 1])


class TestNormalizeStereo48k:
    def test_mono_input(self):
        mono = np.random.randn(24000).astype(np.float32)
        stereo, sr = normalize_stereo_48k(mono, 48000)
        assert stereo.shape == (24000, 2)
        assert sr == 48000

    def test_already_stereo_48k(self):
        audio = np.random.randn(48000, 2).astype(np.float32)
        result, sr = normalize_stereo_48k(audio, 48000)
        assert result.shape == audio.shape
        assert sr == 48000
