#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <algorithm>
#include <cmath>
#include <thread>
#include <chrono>
#include <numeric>

// Tracy性能分析器
#include "tracy/Tracy.hpp"

using namespace std;

// 矩阵乘法 - 计算密集型操作
vector<vector<double>> matrixMultiply(const vector<vector<double>>& A, const vector<vector<double>>& B) {
    ZoneScoped; // Tracy追踪这个函数
    
    size_t n = A.size();
    size_t m = B[0].size();
    size_t p = B.size();
    
    vector<vector<double>> result(n, vector<double>(m, 0.0));
    
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j < m; j++) {
            for (size_t k = 0; k < p; k++) {
                result[i][j] += A[i][k] * B[k][j];
                TracyPlot("matrixMultiply", result[i][j]);
            }
        }
    }
    
    return result;
}

// 生成随机矩阵
vector<vector<double>> generateRandomMatrix(size_t rows, size_t cols) {
    ZoneScoped;
    
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> dis(0.0, 100.0);
    
    vector<vector<double>> matrix(rows, vector<double>(cols));
    for (size_t i = 0; i < rows; i++) {
        for (size_t j = 0; j < cols; j++) {
            matrix[i][j] = dis(gen);
            TracyPlot("generateRandomMatrix", matrix[i][j]);
        }
    }
    
    return matrix;
}

// 快速排序
void quickSort(vector<int>& arr, int low, int high) {
    ZoneScoped;
    
    if (low < high) {
        int pivot = arr[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr[i], arr[j]);
            }
        }
        swap(arr[i + 1], arr[high]);
        int pi = i + 1;

        TracyPlot("quickSort.low", (int64_t)low);
        TracyPlot("quickSort.high", (int64_t)high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

// 计算质数 - 埃拉托斯特尼筛法
vector<int> sieveOfEratosthenes(int n) {
    ZoneScoped;
    
    vector<bool> isPrime(n + 1, true);
    vector<int> primes;
    
    isPrime[0] = isPrime[1] = false;
    
    for (int i = 2; i <= n; i++) {
        if (isPrime[i]) {
            primes.push_back(i);
            for (int j = i * 2; j <= n; j += i) {
                isPrime[j] = false;
                TracyPlot("sieveOfEratosthenes", (isPrime[j] ? 1.0 : 0.0));
            }
        }
    }
    
    return primes;
}

// 计算π值 - 蒙特卡罗方法
double calculatePi(int iterations) {
    ZoneScoped;
    
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> dis(0.0, 1.0);
    
    int insideCircle = 0;
    
    for (int i = 0; i < iterations; i++) {
        double x = dis(gen);
        double y = dis(gen);

        TracyPlot("calculatePi", (x * x + y * y));
        if (x * x + y * y <= 1.0) {
            insideCircle++;
        }
    }
    
    return 4.0 * insideCircle / iterations;
}

// 斐波那契数列（递归）
long long fibonacci(int n) {
    ZoneScoped;
    TracyPlot("fibonacci", (int64_t)n);
    
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 斐波那契数列（动态规划）
long long fibonacciDP(int n) {
    ZoneScoped;
    
    if (n <= 1) return n;
    
    vector<long long> dp(n + 1);
    dp[0] = 0;
    dp[1] = 1;
    
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    
    return dp[n];
}

// 向量点积
double dotProduct(const vector<double>& a, const vector<double>& b) {
    ZoneScoped;
    
    double result = 0.0;
    for (size_t i = 0; i < a.size(); i++) {
        result += a[i] * b[i];
        TracyPlot("dotProduct", result);
    }
    
    return result;
}

// 复杂的数学计算
void complexMathOperations(int iterations) {
    ZoneScoped;
    
    double sum = 0.0;
    for (int i = 1; i <= iterations; i++) {
        sum += sin(i) * cos(i) + tan(i / 100.0) + sqrt(i) + log(i);
        TracyPlot("complexMathOperations", sum);
    }
    
    cout << "复杂数学计算结果: " << sum << endl;
}

// 内存密集型操作
void memoryIntensiveOperation(size_t size) {
    ZoneScoped;
    
    vector<vector<int>> bigArray(size, vector<int>(size, 0));
    
    // 填充数据
    for (size_t i = 0; i < size; i++) {
        for (size_t j = 0; j < size; j++) {
            bigArray[i][j] = static_cast<int>(i * j);
        }
    }
    
    // 计算总和
    long long sum = 0;
    for (size_t i = 0; i < size; i++) {
        for (size_t j = 0; j < size; j++) {
            sum += bigArray[i][j];
        }
    }
    
    cout << "内存密集型操作总和: " << sum << endl;
}

// 多线程测试
void threadWork(int threadId, int workload) {
    ZoneScopedN("ThreadWork"); // 命名追踪区域
    
    // 模拟工作负载
    long long sum = 0;
    for (int i = 0; i < workload; i++) {
        sum += i * threadId;
    }
    
    cout << "线程 " << threadId << " 完成, 结果: " << sum << endl;
}

void multiThreadTest(int numThreads, int workload) {
    ZoneScoped;
    
    vector<thread> threads;
    
    for (int i = 0; i < numThreads; i++) {
        threads.emplace_back(threadWork, i, workload);
    }
    
    for (auto& t : threads) {
        t.join();
    }
}

// 主测试函数
void runPerformanceTests() {
    ZoneScoped;
    
    cout << "\n========== Tracy 性能测试开始 ==========" << endl;
    
    // 测试1: 矩阵乘法
    {
        ZoneScopedN("Matrix Multiplication Test");
        cout << "\n[测试1] 矩阵乘法..." << endl;
        auto A = generateRandomMatrix(200, 200);
        auto B = generateRandomMatrix(200, 200);
        auto C = matrixMultiply(A, B);
        cout << "矩阵乘法完成 (200x200 * 200x200)" << endl;
    }
    
    // 测试2: 快速排序
    {
        ZoneScopedN("Quick Sort Test");
        cout << "\n[测试2] 快速排序..." << endl;
        vector<int> arr(100000);
        random_device rd;
        mt19937 gen(rd());
        uniform_int_distribution<> dis(1, 1000000);
        
        for (int& num : arr) {
            num = dis(gen);
        }
        
        quickSort(arr, 0, arr.size() - 1);
        cout << "排序完成 (100000个元素)" << endl;
    }
    
    // 测试3: 质数计算
    {
        ZoneScopedN("Prime Numbers Test");
        cout << "\n[测试3] 质数计算..." << endl;
        auto primes = sieveOfEratosthenes(1000000);
        cout << "找到 " << primes.size() << " 个质数 (范围: 0-1000000)" << endl;
    }
    
    // 测试4: 蒙特卡罗π值计算
    {
        ZoneScopedN("Monte Carlo Pi Test");
        cout << "\n[测试4] 蒙特卡罗π值计算..." << endl;
        double pi = calculatePi(10000000);
        cout << "π ≈ " << pi << " (10000000次迭代)" << endl;
    }
    
    // 测试5: 斐波那契（递归 vs 动态规划）
    {
        ZoneScopedN("Fibonacci Test");
        cout << "\n[测试5] 斐波那契数列..." << endl;
        
        {
            ZoneScopedN("Fibonacci Recursive");
            long long result = fibonacci(35);
            cout << "递归方法: fibonacci(35) = " << result << endl;
        }
        
        {
            ZoneScopedN("Fibonacci DP");
            long long result = fibonacciDP(90);
            cout << "动态规划: fibonacci(90) = " << result << endl;
        }
    }
    
    // 测试6: 向量运算
    {
        ZoneScopedN("Vector Operations Test");
        cout << "\n[测试6] 向量点积计算..." << endl;
        
        vector<double> v1(10000000);
        vector<double> v2(10000000);
        
        random_device rd;
        mt19937 gen(rd());
        uniform_real_distribution<> dis(0.0, 1.0);
        
        for (size_t i = 0; i < v1.size(); i++) {
            v1[i] = dis(gen);
            v2[i] = dis(gen);
        }
        
        double result = dotProduct(v1, v2);
        cout << "点积结果: " << result << " (10000000维向量)" << endl;
    }
    
    // 测试7: 复杂数学运算
    {
        ZoneScopedN("Complex Math Test");
        cout << "\n[测试7] 复杂数学运算..." << endl;
        complexMathOperations(1000000);
    }
    
    // 测试8: 内存密集型操作
    {
        ZoneScopedN("Memory Intensive Test");
        cout << "\n[测试8] 内存密集型操作..." << endl;
        memoryIntensiveOperation(1000);
    }
    
    // 测试9: 多线程测试
    {
        ZoneScopedN("Multi-Threading Test");
        cout << "\n[测试9] 多线程测试..." << endl;
        multiThreadTest(8, 50000000);
    }
    
    cout << "\n========== 所有测试完成 ==========" << endl;
}

int main()
{
    cout << "Tracy性能分析测试程序" << endl;
    cout << "请确保Tracy Profiler已经运行并连接" << endl;
    cout << "按回车键开始测试..." << endl;
    cin.get();
    
    // 运行多次测试以便在Tracy中观察
    for (int i = 0; i < 3; i++) {
        ZoneScopedN("Main Loop Iteration");
        FrameMark; // Tracy帧标记

        cout << "\n\n============ 第 " << (i + 1) << " 轮测试 ============" << endl;
        runPerformanceTests();

        // 短暂休息，让Tracy更容易区分不同的测试轮次
        this_thread::sleep_for(chrono::milliseconds(500));
    }
    
    cout << "\n程序即将退出，按回车键继续..." << endl;
    cin.get();
    
    return 0;
}