"""
Comprehensive test script for Arrangement injection and related fixes.
Tests: coherence_system, audio_analyzer_dual, bus_architecture
ASCII-only to avoid encoding issues.
"""
import sys
import os

def test_header(name):
    print(f"\n{'='*60}")
    print(f"TEST: {name}")
    print('='*60)

def test_result(success, message):
    status = "PASS" if success else "FAIL"
    print(f"  [{status}] {message}")
    return success

def main():
    print("\n" + "="*60)
    print("ABLETON MCP AI - COMPREHENSIVE TEST SUITE")
    print("="*60)
    
    results = {"passed": 0, "failed": 0}
    
    # Test 1: Coherence System (standalone)
    test_header("1. COHERENCE SYSTEM (Standalone)")
    try:
        # Try importing without going through AbletonMCP_AI.__init__
        import importlib.util
        spec = importlib.util.spec_from_file_location(
            "coherence_system",
            "AbletonMCP_AI/mcp_server/engines/coherence_system.py"
        )
        coherence_module = importlib.util.module_from_spec(spec)
        
        # Need to mock the numpy dependencies
        import types
        mock_np = types.ModuleType('numpy')
        mock_np.float32 = float
        mock_np.array = lambda x: x
        mock_np.mean = lambda x: sum(x)/len(x) if x else 0
        sys.modules['numpy'] = mock_np
        
        spec.loader.exec_module(coherence_module)
        
        test_result(True, "Coherence system loaded (mocked numpy)")
        results["passed"] += 1
        
        # Test basic functionality
        try:
            CoherenceFeatures = coherence_module.CoherenceFeatures
            features1 = CoherenceFeatures(bpm=95.0, key="Am", spectral_centroid=500.0, mfcc_mean=0.5)
            features2 = CoherenceFeatures(bpm=95.5, key="Am", spectral_centroid=510.0, mfcc_mean=0.52)
            coherence = coherence_module.calculate_comprehensive_coherence(features1, features2)
            test_result(True, f"Coherence calculation works: score={coherence.overall:.3f}")
            results["passed"] += 1
        except Exception as e:
            test_result(False, f"Coherence calculation failed: {e}")
            results["failed"] += 1
            
    except Exception as e:
        test_result(False, f"Coherence import failed: {e}")
        results["failed"] += 2
    
    # Test 2: Audio Analyzer Dual (standalone)
    test_header("2. AUDIO ANALYZER DUAL (Standalone)")
    try:
        import importlib.util
        spec = importlib.util.spec_from_file_location(
            "audio_analyzer_dual",
            "AbletonMCP_AI/mcp_server/engines/audio_analyzer_dual.py"
        )
        audio_module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(audio_module)
        
        AudioAnalyzerDual = audio_module.AudioAnalyzerDual
        analyzer = AudioAnalyzerDual(backend="basic")
        test_result(True, "AudioAnalyzerDual instantiated with basic backend")
        results["passed"] += 1
        
        # Try to analyze a sample if libreria exists
        test_path = "libreria/reggaeton/kick/kick 1.wav"
        if os.path.exists(test_path):
            try:
                features = analyzer.analyze_sample(test_path)
                test_result(True, f"Audio analysis: BPM={features.bpm}, Key={features.key}")
                results["passed"] += 1
            except Exception as e:
                test_result(False, f"Audio analysis failed: {e}")
                results["failed"] += 1
        else:
            test_result(True, f"Sample path not found (expected): {test_path}")
            test_result(True, "AudioAnalyzerDual is importable and functional")
            results["passed"] += 2
            
    except Exception as e:
        test_result(False, f"AudioAnalyzerDual import failed: {e}")
        results["failed"] += 3
    
    # Test 3: Bus Architecture
    test_header("3. BUS ARCHITECTURE")
    try:
        import importlib.util
        spec = importlib.util.spec_from_file_location(
            "bus_architecture",
            "AbletonMCP_AI/mcp_server/engines/bus_architecture.py"
        )
        bus_module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(bus_module)
        
        BUS_GAIN_CALIBRATION = bus_module.BUS_GAIN_CALIBRATION
        bus_count = len(BUS_GAIN_CALIBRATION)
        test_result(True, f"Bus config loaded: {bus_count} buses")
        results["passed"] += 1
        
        # Verify specific buses exist
        expected_buses = ["DRUM_BUS", "BASS_BUS", "MIX_BUS", "MASTER_CHAIN"]
        for bus in expected_buses:
            if bus in BUS_GAIN_CALIBRATION:
                test_result(True, f"Bus '{bus}' configured")
                results["passed"] += 1
            else:
                test_result(False, f"Bus '{bus}' missing")
                results["failed"] += 1
                
    except Exception as e:
        test_result(False, f"Bus architecture import failed: {e}")
        results["failed"] += 5
    
    # Test 4: Arrangement Tools - check files exist
    test_header("4. ARRANGEMENT TOOLS (File Check)")
    arrangement_files = [
        "AbletonMCP_AI/mcp_server/server.py",
        "AbletonMCP_AI/mcp_server/engines/arrangement_injection.py",
        "AbletonMCP_AI/mcp_server/engines/timeline_builder.py",
    ]
    
    for filepath in arrangement_files:
        if os.path.exists(filepath):
            test_result(True, f"File exists: {filepath}")
            results["passed"] += 1
        else:
            test_result(False, f"File missing: {filepath}")
            results["failed"] += 1
    
    # Check for arrangement functions in server.py
    try:
        with open("AbletonMCP_AI/mcp_server/server.py", 'r') as f:
            content = f.read()
            
        expected_functions = [
            "build_arrangement_timeline",
            "create_arrangement_track",
            "create_arrangement_audio_pattern",
            "get_arrangement_status",
            "create_section_at_bar"
        ]
        
        for func in expected_functions:
            if f"def {func}(" in content or f"async def {func}(" in content:
                test_result(True, f"Function defined: {func}")
                results["passed"] += 1
            else:
                test_result(False, f"Function missing: {func}")
                results["failed"] += 1
                
    except Exception as e:
        test_result(False, f"Could not read server.py: {e}")
        results["failed"] += 5
    
    # Test 5: Intelligent Track Generator (standalone)
    test_header("5. INTELLIGENT TRACK GENERATOR (Standalone)")
    try:
        import importlib.util
        spec = importlib.util.spec_from_file_location(
            "intelligent_track_generator",
            "AbletonMCP_AI/mcp_server/engines/intelligent_track_generator.py"
        )
        itg_module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(itg_module)
        
        test_result(True, "IntelligentTrackGenerator module loaded")
        results["passed"] += 1
        
        # Test basic instantiation
        try:
            config_class = itg_module.IntelligentTrackConfig
            config = config_class(
                description="reggaeton 95bpm Am",
                structure_type="short"
            )
            test_result(True, f"Config created: {config.description}")
            results["passed"] += 1
        except Exception as e:
            test_result(False, f"Config creation failed: {e}")
            results["failed"] += 1
            
    except Exception as e:
        test_result(False, f"IntelligentTrackGenerator import failed: {e}")
        results["failed"] += 2
    
    # Manual MCP Test Instructions
    test_header("6. MANUAL MCP TEST INSTRUCTIONS")
    print("""
The following tests must be run via MCP when Ableton Live is running:

TEST 6a: create_arrangement_audio_pattern
  1. Ensure Ableton Live is running with MCP connection
  2. Run: create_arrangement_audio_pattern with:
     - track_index: 0
     - file_path: "libreria/reggaeton/kick/kick 1.wav"
     - positions: [0, 2, 4, 6]
     - name: "Test Kick Pattern"
  3. Verify: Clips appear in Arrangement View at bars 0, 2, 4, 6

TEST 6b: build_arrangement_timeline
  1. Ensure Ableton Live is running with MCP connection
  2. Run: build_arrangement_timeline with:
     - sections_json: '[
         {"name": "Intro", "start_bar": 0, "duration_bars": 4,
          "tracks": [{"type": "drums", "variation": "minimal"}]},
         {"name": "Verse", "start_bar": 4, "duration_bars": 8,
          "tracks": [{"type": "drums", "variation": "full"},
                     {"type": "bass", "variation": "standard"}]}
       ]'
  3. Verify: Two sections created in Arrangement View

TEST 6c: get_arrangement_status
  1. Run: get_arrangement_status
  2. Verify: Returns current clips in Arrangement View
  3. Check: total_clips > 0 after running tests 6a or 6b

TEST 6d: create_arrangement_track
  1. Run: create_arrangement_track with track_type="drums"
  2. Verify: New track created in Arrangement View
  3. Run: create_section_at_bar with section_type="intro", at_bar=0
  4. Verify: Section created on the track

TEST 6e: generate_intelligent_track
  1. Run: generate_intelligent_track with:
     - description: "reggaeton 95bpm Am"
     - structure_type: "short"
  2. Verify: Complete track generated with coherence > 0.9
  3. Check: Clips appear in Arrangement View
""")
    
    # Sample library check
    test_header("7. SAMPLE LIBRARY CHECK")
    libreria_path = "libreria"
    if os.path.exists(libreria_path):
        test_result(True, f"Sample library exists: {libreria_path}")
        results["passed"] += 1
        
        # Count samples
        sample_count = 0
        for root, dirs, files in os.walk(libreria_path):
            for file in files:
                if file.endswith(('.wav', '.mp3', '.aif')):
                    sample_count += 1
        
        test_result(True, f"Total samples found: {sample_count}")
        results["passed"] += 1
    else:
        test_result(False, f"Sample library not found: {libreria_path}")
        results["failed"] += 2
    
    # Summary
    test_header("TEST SUMMARY")
    total = results["passed"] + results["failed"]
    print(f"  Total tests: {total}")
    print(f"  Passed: {results['passed']}")
    print(f"  Failed: {results['failed']}")
    
    if results["failed"] == 0:
        print("\n  *** ALL TESTS PASSED ***")
        return 0
    else:
        print(f"\n  *** {results['failed']} TEST(S) FAILED ***")
        return 1

if __name__ == "__main__":
    sys.exit(main())
