#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <QThread>
#include <chrono>
#include <thread>

#include "AVPlayer2/PlayWidget.h"
#include "AVPlayer2/playercontroller.h"

/**
 * @brief 压力测试PlayerController的线程安全性
 * 
 * 这个测试程序验证PlayerController在暴力调用startToPlay时的稳定性
 */
class PlayerStressTest : public QObject
{
    Q_OBJECT

public:
    explicit PlayerStressTest(QObject* parent = nullptr)
        : QObject(parent)
        , m_playWidget(new PlayWidget)
    {
        m_playWidget->resize(960, 540);
        m_playWidget->show();
    }
    
    ~PlayerStressTest()
    {
        delete m_playWidget;
    }
    
    void runStressTest()
    {
        qDebug() << "开始PlayerController压力测试...";
        
        // 测试1: 快速连续调用
        qDebug() << "测试1: 快速连续调用startToPlay (20次)";
        for (int i = 0; i < 20; ++i) {
            m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
            qDebug() << "调用" << (i + 1) << "/20";
        }
        
        // 等待一段时间让请求处理完成
        QTimer::singleShot(2000, [this]() {
            // 测试2: 多线程并发调用
            qDebug() << "测试2: 多线程并发调用startToPlay";
            runConcurrentTest();
        });
        
        // 测试3: 交替播放和停止
        QTimer::singleShot(5000, [this]() {
            qDebug() << "测试3: 交替播放和停止";
            runAlternatingTest();
        });
        
        // 测试4: 不同文件的快速切换
        QTimer::singleShot(8000, [this]() {
            qDebug() << "测试4: 不同文件的快速切换";
            runFileSwitchTest();
        });
        
        // 测试完成
        QTimer::singleShot(12000, [this]() {
            qDebug() << "所有压力测试完成！";
            QApplication::quit();
        });
    }
    
private:
    void runConcurrentTest()
    {
        // 创建多个线程同时调用startToPlay
        std::vector<std::thread> threads;
        
        for (int i = 0; i < 5; ++i) {
            threads.emplace_back([this, i]() {
                for (int j = 0; j < 10; ++j) {
                    // 使用QMetaObject::invokeMethod确保在主线程中调用
                    QMetaObject::invokeMethod(this, [this]() {
                        m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
                    }, Qt::QueuedConnection);
                    
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                }
            });
        }
        
        // 等待所有线程完成
        for (auto& thread : threads) {
            thread.join();
        }
        
        qDebug() << "并发测试完成";
    }
    
    void runAlternatingTest()
    {
        // 交替调用播放和停止
        for (int i = 0; i < 10; ++i) {
            m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
            
            QTimer::singleShot(100, [this]() {
                // 假设PlayWidget有stopPlay方法，如果没有可以通过PlayerController调用
                // m_playWidget->stopPlay();
            });
            
            std::this_thread::sleep_for(std::chrono::milliseconds(200));
        }
        
        qDebug() << "交替测试完成";
    }
    
    void runFileSwitchTest()
    {
        // 快速切换不同文件（如果有多个测试文件的话）
        QStringList testFiles = {
            "C:/Users/zhuizhu/Videos/2.mp4",
            "C:/Users/zhuizhu/Videos/2.mp4", // 重复文件测试去重功能
            "C:/Users/zhuizhu/Videos/2.mp4"
        };
        
        for (int i = 0; i < 15; ++i) {
            QString file = testFiles[i % testFiles.size()];
            m_playWidget->startToPlay(file);
            qDebug() << "切换到文件:" << file;
            std::this_thread::sleep_for(std::chrono::milliseconds(50));
        }
        
        qDebug() << "文件切换测试完成";
    }
    
private:
    PlayWidget* m_playWidget;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    // 启用详细日志
    QLoggingCategory::setFilterRules("player.controller.debug=true");
    
    PlayerStressTest test;
    
    // 延迟启动测试，确保UI完全初始化
    QTimer::singleShot(1000, &test, &PlayerStressTest::runStressTest);
    
    return app.exec();
}

#include "test_player_stress.moc"