"""Unit tests for apply_fade function."""
import unittest
from pathlib import Path
import numpy as np
import soundfile as sf

from reaper_mcp.audio.audio_processing import apply_fade
from tests.base import TempDirTestCase


class TestApplyFade(TempDirTestCase):
    """Tests for the apply_fade function."""
    
    def setUp(self):
        """Set up test fixtures."""
        super().setUp()
        self.test_file = self.temp_dir / "test_audio.wav"
        
        # Create a simple test audio file
        sample_rate = 44100
        duration = 2.0
        t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
        audio = 0.5 * np.sin(2 * np.pi * 440.0 * t)
        sf.write(self.test_file, audio, sample_rate)
    
    def test_apply_fade_in(self):
        """Test applying fade in."""
        result = apply_fade(self.test_file, fade_in=0.5, fade_out=0.0)
        
        self.assertNotIn("error", result)
        self.assertIn("file_path", result)
        self.assertTrue(Path(result["file_path"]).exists())
        
        # Verify audio has fade in
        audio, sr = sf.read(result["file_path"])
        original_audio, _ = sf.read(self.test_file)
        
        # Start should be quieter than original
        self.assertLess(np.max(np.abs(audio[:1000])), np.max(np.abs(original_audio[:1000])))
        
        # End should be similar to original
        self.assertAlmostEqual(np.max(np.abs(audio[-10000:])), np.max(np.abs(original_audio[-10000:])), places=1)
        
        # Clean up
        Path(result["file_path"]).unlink()
    
    def test_apply_fade_out(self):
        """Test applying fade out."""
        result = apply_fade(self.test_file, fade_in=0.0, fade_out=0.5)
        
        self.assertNotIn("error", result)
        self.assertIn("file_path", result)
        
        # Verify audio has fade out
        audio, sr = sf.read(result["file_path"])
        original_audio, _ = sf.read(self.test_file)
        
        # Start should be similar to original
        self.assertAlmostEqual(np.max(np.abs(audio[:10000])), np.max(np.abs(original_audio[:10000])), places=1)
        
        # End should be quieter
        self.assertLess(np.max(np.abs(audio[-1000:])), np.max(np.abs(original_audio[-1000:])))
        
        # Clean up
        Path(result["file_path"]).unlink()
    
    def test_apply_fade_both(self):
        """Test applying both fade in and fade out."""
        result = apply_fade(self.test_file, fade_in=0.3, fade_out=0.3)
        
        self.assertNotIn("error", result)
        self.assertTrue(Path(result["file_path"]).exists())
        
        # Verify audio
        audio, sr = sf.read(result["file_path"])
        self.assertEqual(sr, 44100)
        
        # Clean up
        Path(result["file_path"]).unlink()
    
    def test_apply_fade_no_fade(self):
        """Test with no fade (should still work)."""
        result = apply_fade(self.test_file, fade_in=0.0, fade_out=0.0)
        
        self.assertNotIn("error", result)
        self.assertTrue(Path(result["file_path"]).exists())
        
        # Clean up
        Path(result["file_path"]).unlink()
    
    def test_apply_fade_nonexistent_file(self):
        """Test applying fade to nonexistent file."""
        result = apply_fade("/nonexistent/file.wav", fade_in=0.5)
        
        self.assertIn("error", result)
