import os
import numpy as np
import soundfile as sf
import sys

# 确保能找到 src/multimetric_eval 模块
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))

from multimetric_eval import ParalinguisticEvaluator

def create_dummy_audio(filename, duration=1.0, sr=48000):
    """生成一段随机白噪声并保存为 wav 文件，模拟实际音频"""
    # 降低音量以防万一被听到
    audio = np.random.randn(int(duration * sr)) * 0.01  
    sf.write(filename, audio, sr)

def run_tests():
    test_dir = "temp_test_audios"
    os.makedirs(test_dir, exist_ok=True)
    
    # 构建测试所需的 source 和 target 路径
    src_paths = [os.path.join(test_dir, "src_1.wav"), os.path.join(test_dir, "src_2.wav")]
    tgt_paths = [os.path.join(test_dir, "tgt_1.wav"), os.path.join(test_dir, "tgt_2.wav")]
    
    print("⏳ [1] 正在生成虚拟音频文件用于测试...")
    for p in src_paths + tgt_paths:
        create_dummy_audio(p)
        
    try:
        print("\n⏳ [2] 正在初始化 ParalinguisticEvaluator...")
        # 默认会触发 laion/clap-htatsc-base 模型的下载或加载
        evaluator = ParalinguisticEvaluator(
            use_continuous_fidelity=True,
            use_discrete_matching=True
        )
        
        print("\n⏳ [3] 正在运行测试: evaluate_all ...")
        results = evaluator.evaluate_all(
            source_audio=src_paths,
            target_audio=tgt_paths,
            verbose=True
        )
        
        print("\n================ 测试结果 ================")
        print(f"返回类型: {type(results)}")
        print(f"数据内容: {results}")
        
        # 断言验证模块完整性
        assert isinstance(results, dict), "返回值必须是字典"
        assert "Paralinguistic_Fidelity_Cosine" in results, "缺少连续保真度结果"
        assert "Event_Retention_F1" in results, "缺少离散保留率结果"
        
        print("✅ 模块所有子功能全部测试通过！Pipeline运行正常。")
        
    except Exception as e:
        print(f"\n❌ 测试过程中发生错误: {e}")
        import traceback
        traceback.print_exc()
        
    finally:
        print("\n🧹 [4] 正在清理临时测试音频...")
        for p in src_paths + tgt_paths:
            if os.path.exists(p):
                os.remove(p)
        if os.path.exists(test_dir):
            os.rmdir(test_dir)

if __name__ == "__main__":
    run_tests()