"""
Tests for CLI functionality.
"""

import unittest
from pathlib import Path
import tempfile
import json
import sys
import os

# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))

from src.cli.main import MusicBrainzCleaner


class TestCLI(unittest.TestCase):
    """Test cases for CLI functionality."""
    
    def setUp(self):
        """Set up test fixtures."""
        self.temp_dir = tempfile.mkdtemp()
        self.cleaner = MusicBrainzCleaner()
        
        # Create test song data
        self.test_songs = [
            {
                "artist": "Test Artist",
                "title": "Test Song",
                "disabled": False,
                "favorite": True,
                "guid": "test-guid-123",
                "path": "/test/path/song.mp3"
            }
        ]
    
    def tearDown(self):
        """Clean up test fixtures."""
        import shutil
        shutil.rmtree(self.temp_dir)
    
    def test_clean_artist_name(self):
        """Test artist name cleaning functionality."""
        # Test basic cleaning
        result = self.cleaner._clean_artist_name("  Test Artist  ")
        self.assertEqual(result, "Test Artist")
        
        # Test name variations (these would be loaded from data file)
        # Note: This test assumes the data file has the variations
        result = self.cleaner._clean_artist_name("ACDC")
        # Should be cleaned to "AC/DC" if the data file contains this variation
    
    def test_clean_title(self):
        """Test title cleaning functionality."""
        # Test karaoke suffix removal
        result = self.cleaner._clean_title("Test Song (Karaoke Version)")
        self.assertEqual(result, "Test Song")
        
        # Test instrumental suffix removal
        result = self.cleaner._clean_title("Test Song (Instrumental)")
        self.assertEqual(result, "Test Song")
        
        # Test multiple suffixes
        result = self.cleaner._clean_title("Test Song (Karaoke Version) (Instrumental)")
        self.assertEqual(result, "Test Song")
        
        # Test no suffix
        result = self.cleaner._clean_title("Test Song")
        self.assertEqual(result, "Test Song")
    
    def test_clean_song_structure(self):
        """Test that clean_song preserves song structure."""
        test_song = self.test_songs[0].copy()
        
        # Mock the find_artist_mbid and find_recording_mbid methods
        original_find_artist = self.cleaner.find_artist_mbid
        original_find_recording = self.cleaner.find_recording_mbid
        original_get_artist_info = self.cleaner.get_artist_info
        original_get_recording_info = self.cleaner.get_recording_info
        
        def mock_find_artist_mbid(artist_name):
            return "test-artist-mbid-123"
        
        def mock_find_recording_mbid(artist_mbid, title):
            return "test-recording-mbid-456"
        
        def mock_get_artist_info(mbid):
            return {"name": "Test Artist", "id": mbid}
        
        def mock_get_recording_info(mbid):
            return {"title": "Test Song", "id": mbid}
        
        self.cleaner.find_artist_mbid = mock_find_artist_mbid
        self.cleaner.find_recording_mbid = mock_find_recording_mbid
        self.cleaner.get_artist_info = mock_get_artist_info
        self.cleaner.get_recording_info = mock_get_recording_info
        
        try:
            result = self.cleaner.clean_song(test_song)
            
            # Check that original fields are preserved
            self.assertEqual(result["artist"], "Test Artist")
            self.assertEqual(result["title"], "Test Song")
            self.assertEqual(result["disabled"], False)
            self.assertEqual(result["favorite"], True)
            self.assertEqual(result["guid"], "test-guid-123")
            self.assertEqual(result["path"], "/test/path/song.mp3")
            
            # Check that new fields are added
            self.assertIn("mbid", result)
            self.assertIn("recording_mbid", result)
            
        finally:
            # Restore original methods
            self.cleaner.find_artist_mbid = original_find_artist
            self.cleaner.find_recording_mbid = original_find_recording
            self.cleaner.get_artist_info = original_get_artist_info
            self.cleaner.get_recording_info = original_get_recording_info
    
    def test_file_processing_with_limit(self):
        """Test file processing with limit parameter."""
        # Create test input file
        input_file = Path(self.temp_dir) / "test_songs.json"
        with open(input_file, 'w') as f:
            json.dump(self.test_songs * 3, f)  # Create 3 copies of test song
        
        # Test with limit
        output_file = Path(self.temp_dir) / "output.json"
        
        # Mock the clean_song method to avoid API calls
        original_clean_song = self.cleaner.clean_song
        
        def mock_clean_song(song):
            song_copy = song.copy()
            song_copy["mbid"] = "test-mbid"
            song_copy["recording_mbid"] = "test-recording-mbid"
            return song_copy
        
        self.cleaner.clean_song = mock_clean_song
        
        try:
            result_path = self.cleaner.clean_songs_file(input_file, output_file, limit=2)
            
            # Check that output file was created
            self.assertTrue(output_file.exists())
            
            # Check that only 2 songs were processed
            with open(output_file, 'r') as f:
                output_data = json.load(f)
                self.assertEqual(len(output_data), 2)
                
        finally:
            # Restore original method
            self.cleaner.clean_song = original_clean_song


if __name__ == '__main__':
    unittest.main() 