#include "code/codec/codec_audio_encoder.h"
#include "code/base/logger.h"
#include "code/base/media_common.h"
#include <iostream>
#include <vector>
#include <memory>
#include <chrono>
#include <fstream>
#include <algorithm>
#include <cmath>

using namespace av;
using namespace av::codec;

/**
 * 音频编码器测试类
 */
class AudioEncoderTester {
public:
    AudioEncoderTester() {
        Logger::instance().setLevel(LogLevel::DEBUG);
        Logger::instance().info("=== 音频编码器测试套件 ===");
    }
    
    /**
     * 测试基本音频编码功能
     */
    bool testBasicAudioEncoding() {
        Logger::instance().info("[测试] 基本音频编码功能...");
        
        try {
            // 创建音频编码器
            auto encoder = AudioEncoderFactory::create("aac");
            if (!encoder) {
                Logger::instance().error("[失败] 无法创建AAC编码器");
                return false;
            }
            
            // 设置编码参数
            AudioEncoderParams params;
            params.codecName = "aac";
            params.bitRate = 128000;
            params.sampleRate = 44100;
            params.channels = 2;
            params.channelLayout = AV_CHANNEL_LAYOUT_STEREO;
            params.sampleFormat = AV_SAMPLE_FMT_FLTP;
            params.frameSize = 1024;
            
            // 打开编码器
            ErrorCode result = encoder->open(params);
            if (result != ErrorCode::SUCCESS) {
                Logger::instance().errorf("[失败] 打开编码器失败: {}", static_cast<int>(result));
                return false;
            }
            
            // 创建测试音频帧
            AVFramePtr frame = createTestAudioFrame(params);
            if (!frame) {
                Logger::instance().error("[失败] 创建测试音频帧失败");
                return false;
            }
            
            // 编码音频帧
            std::vector<AVPacketPtr> packets;
            result = encoder->encode(frame, packets);
            if (result != ErrorCode::SUCCESS) {
                Logger::instance().errorf("[失败] 编码音频帧失败: {}", static_cast<int>(result));
                return false;
            }
            
            Logger::instance().infof("[成功] 编码产生了 {} 个数据包", packets.size());
            
            // 关闭编码器
            encoder->close();
            
            Logger::instance().info("[成功] 基本音频编码测试通过");
            return true;
            
        } catch (const std::exception& e) {
            Logger::instance().errorf("[异常] {}", e.what());
            return false;
        }
    }
    
    /**
     * 测试多种音频编码器
     */
    bool testMultipleEncoders() {
        Logger::instance().info("[测试] 多种音频编码器支持...");
        
        auto supportedEncoders = AudioEncoder::getSupportedEncoders();
        Logger::instance().infof("支持的编码器数量: {}", supportedEncoders.size());
        
        if (supportedEncoders.empty()) {
            Logger::instance().warning("[警告] 没有找到支持的音频编码器");
            return false;
        }
        
        int successCount = 0;
        // 只测试几个主要的编码器，避免实验性编码器导致的问题
        std::vector<std::string> testEncoders = {"aac", "libmp3lame", "libopus", "flac"};
        
        for (const auto& codecName : testEncoders) {
            // 检查编码器是否在支持列表中
            if (std::find(supportedEncoders.begin(), supportedEncoders.end(), codecName) == supportedEncoders.end()) {
                Logger::instance().infof("跳过不支持的编码器: {}", codecName);
                continue;
            }
            
            Logger::instance().infof("测试编码器: {}", codecName);
            
            try {
                auto encoder = AudioEncoderFactory::create(codecName);
                if (!encoder) {
                    Logger::instance().errorf("  [失败] 无法创建编码器: {}", codecName);
                    continue;
                }
                
                AudioEncoderParams params;
                params.codecName = codecName;
                params.bitRate = 128000;
                params.sampleRate = 44100;
                params.channels = 2;
                params.channelLayout = AV_CHANNEL_LAYOUT_STEREO;
                params.sampleFormat = AV_SAMPLE_FMT_FLTP;
                
                ErrorCode result = encoder->open(params);
                if (result == ErrorCode::SUCCESS) {
                    Logger::instance().infof("  [成功] {} 编码器打开成功", codecName);
                    successCount++;
                } else {
                    Logger::instance().errorf("  [失败] {} 编码器打开失败: {}", codecName, static_cast<int>(result));
                }
                
                // 确保编码器正确关闭
                encoder->close();
                encoder.reset(); // 释放编码器资源
                
            } catch (const std::exception& e) {
                Logger::instance().errorf("  [异常] 测试编码器 {} 时发生异常: {}", codecName, e.what());
            }
        }
        
        Logger::instance().infof("成功测试的编码器: {}/{}", successCount, testEncoders.size());
        return successCount > 0;
    }
    
    /**
     * 测试音频重采样功能
     */
    bool testAudioResampling() {
        Logger::instance().info("[测试] 音频重采样功能...");
        
        try {
            AudioResampler resampler;
            
            // 设置重采样参数：从48kHz立体声转换为44.1kHz立体声
            AVChannelLayout srcLayout = AV_CHANNEL_LAYOUT_STEREO;
            AVChannelLayout dstLayout = AV_CHANNEL_LAYOUT_STEREO;
            
            bool result = resampler.init(srcLayout, AV_SAMPLE_FMT_FLTP, 48000,
                                       dstLayout, AV_SAMPLE_FMT_FLTP, 44100);
            if (!result) {
                Logger::instance().error("[失败] 初始化重采样器失败");
                return false;
            }
            
            // 创建测试音频帧
            AudioEncoderParams params;
            params.sampleRate = 48000;
            params.channels = 2;
            params.sampleFormat = AV_SAMPLE_FMT_FLTP;
            
            AVFramePtr srcFrame = createTestAudioFrame(params);
            if (!srcFrame) {
                Logger::instance().error("[失败] 创建源音频帧失败");
                return false;
            }
            
            // 执行重采样
            AVFramePtr dstFrame = resampler.resample(srcFrame);
            if (!dstFrame) {
                Logger::instance().error("[失败] 音频重采样失败");
                return false;
            }
            
            Logger::instance().infof("[成功] 重采样: {}Hz -> {}Hz", srcFrame->sample_rate, dstFrame->sample_rate);
            Logger::instance().infof("[成功] 样本数: {} -> {}", srcFrame->nb_samples, dstFrame->nb_samples);
            
            return true;
            
        } catch (const std::exception& e) {
            Logger::instance().errorf("[异常] {}", e.what());
            return false;
        }
    }
    
    /**
     * 测试编码器工厂
     */
    bool testEncoderFactory() {
        Logger::instance().info("[测试] 编码器工厂功能...");
        
        // 测试创建最佳编码器
        auto bestEncoder = AudioEncoderFactory::createBest();
        if (!bestEncoder) {
            Logger::instance().error("[失败] 无法创建最佳编码器");
            return false;
        }
        Logger::instance().info("[成功] 创建最佳编码器");
        
        // 测试创建无损编码器
        auto losslessEncoder = AudioEncoderFactory::createLossless();
        if (!losslessEncoder) {
            Logger::instance().error("[失败] 无法创建无损编码器");
            return false;
        }
        Logger::instance().info("[成功] 创建无损编码器");
        
        // 测试推荐编码器
        std::string recommended = AudioEncoder::getRecommendedEncoder();
        if (recommended.empty()) {
            Logger::instance().error("[失败] 无法获取推荐编码器");
            return false;
        }
        Logger::instance().infof("[成功] 推荐编码器: {}", recommended);
        
        return true;
    }
    
    /**
     * 测试编码器状态管理
     */
    bool testEncoderStateManagement() {
        Logger::instance().info("[测试] 编码器状态管理...");
        
        try {
            auto encoder = AudioEncoderFactory::create("aac");
            if (!encoder) {
                Logger::instance().error("[失败] 无法创建编码器");
                return false;
            }
            
            // 测试初始状态
            if (encoder->getState() != CodecState::IDLE) {
                Logger::instance().error("[失败] 初始状态不正确");
                return false;
            }
            
            // 测试打开编码器
            AudioEncoderParams params;
            params.codecName = "aac";
            params.bitRate = 128000;
            params.sampleRate = 44100;
            params.channels = 2;
            
            ErrorCode result = encoder->open(params);
            if (result != ErrorCode::SUCCESS) {
                Logger::instance().error("[失败] 打开编码器失败");
                return false;
            }
            
            if (encoder->getState() != CodecState::OPENED) {
                Logger::instance().error("[失败] 打开后状态不正确");
                return false;
            }
            
            // 测试关闭编码器
            encoder->close();
            if (encoder->getState() != CodecState::CLOSED) {
                Logger::instance().error("[失败] 关闭后状态不正确");
                return false;
            }
            
            Logger::instance().info("[成功] 编码器状态管理测试通过");
            return true;
            
        } catch (const std::exception& e) {
            Logger::instance().errorf("[异常] {}", e.what());
            return false;
        }
    }
    
    /**
     * 测试错误处理
     */
    bool testErrorHandling() {
        Logger::instance().info("[测试] 错误处理...");
        
        try {
            // 测试无效编码器名称
            auto encoder = AudioEncoderFactory::create("invalid_codec");
            if (encoder) {
                AudioEncoderParams params;
                params.codecName = "invalid_codec";
                ErrorCode result = encoder->open(params);
                if (result == ErrorCode::SUCCESS) {
                    Logger::instance().error("[失败] 应该拒绝无效编码器");
                    return false;
                }
            }
            
            // 测试无效参数
            encoder = AudioEncoderFactory::create("aac");
            if (encoder) {
                AudioEncoderParams params;
                params.codecName = "aac";
                params.sampleRate = -1; // 无效采样率
                params.channels = 0;    // 无效声道数
                
                ErrorCode result = encoder->open(params);
                if (result == ErrorCode::SUCCESS) {
                    Logger::instance().error("[失败] 应该拒绝无效参数");
                    return false;
                }
            }
            
            Logger::instance().info("[成功] 错误处理测试通过");
            return true;
            
        } catch (const std::exception& e) {
            Logger::instance().errorf("[异常] {}", e.what());
            return false;
        }
    }
    
    /**
     * 运行所有测试
     */
    bool runAllTests() {
        Logger::instance().info("开始运行音频编码器测试套件...");
        
        bool allPassed = true;
        
        allPassed &= testBasicAudioEncoding();
        allPassed &= testMultipleEncoders();
        allPassed &= testAudioResampling();
        allPassed &= testEncoderFactory();
        allPassed &= testEncoderStateManagement();
        allPassed &= testErrorHandling();
        
        Logger::instance().info("=== 测试结果 ===");
        if (allPassed) {
            Logger::instance().info("[成功] 所有音频编码器测试通过!");
        } else {
            Logger::instance().error("[失败] 部分测试失败!");
        }
        
        return allPassed;
    }
    
private:
    /**
     * 创建测试音频帧
     */
    AVFramePtr createTestAudioFrame(const AudioEncoderParams& params) {
        AVFramePtr frame = makeAVFrame();
        if (!frame) {
            return nullptr;
        }
        
        frame->format = params.sampleFormat;
        frame->sample_rate = params.sampleRate;
        frame->nb_samples = params.frameSize > 0 ? params.frameSize : 1024;
        
        // 设置声道布局
        if (params.channelLayout.nb_channels > 0) {
            av_channel_layout_copy(&frame->ch_layout, &params.channelLayout);
        } else {
            av_channel_layout_default(&frame->ch_layout, params.channels);
        }
        
        // 分配音频缓冲区
        int ret = av_frame_get_buffer(frame.get(), 0);
        if (ret < 0) {
            return nullptr;
        }
        
        // 填充测试数据（简单的正弦波）
        fillTestAudioData(frame.get());
        
        return frame;
    }
    
    /**
     * 填充测试音频数据
     */
    void fillTestAudioData(AVFrame* frame) {
        if (frame->format == AV_SAMPLE_FMT_FLTP) {
            // 浮点平面格式
            for (int ch = 0; ch < frame->ch_layout.nb_channels; ch++) {
                float* data = reinterpret_cast<float*>(frame->data[ch]);
                for (int i = 0; i < frame->nb_samples; i++) {
                    // 生成440Hz正弦波
                    double t = static_cast<double>(i) / frame->sample_rate;
                    data[i] = static_cast<float>(0.5 * sin(2.0 * M_PI * 440.0 * t));
                }
            }
        } else if (frame->format == AV_SAMPLE_FMT_S16) {
            // 16位整数格式
            int16_t* data = reinterpret_cast<int16_t*>(frame->data[0]);
            for (int i = 0; i < frame->nb_samples * frame->ch_layout.nb_channels; i++) {
                double t = static_cast<double>(i / frame->ch_layout.nb_channels) / frame->sample_rate;
                data[i] = static_cast<int16_t>(16384 * sin(2.0 * M_PI * 440.0 * t));
            }
        }
    }
};

int main() {
    try {
        AudioEncoderTester tester;
        bool success = tester.runAllTests();
        return success ? 0 : 1;
    } catch (const std::exception& e) {
        Logger::instance().errorf("测试程序异常: {}", e.what());
        return 1;
    }
}