#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <condition_variable>
#include "threadpool.hpp"
#include "http.hpp"
#include <chrono>

std::mutex mtx;  // Mutex to protect shared data
int threads_working = 0;

// Function to simulate work that requires thread synchronization
void incThreadsWorking() {
    mtx.lock();  // Lock the mutex to enter the critical section
    threads_working++;
    mtx.unlock();  // Unlock the mutex to allow other threads to enter the critical section
}
void decThreadsWorking(){
    mtx.lock();
    threads_working--;
    mtx.unlock();
}

int main(int argc, char* argv[]) {
    const char* url = nullptr;
    int threadCount = 10; // Default value
    int requestCount = 1000; // Default value

    // Parse command-line arguments
    for (int i = 1; i < argc; ++i) {
        if (std::string(argv[i]) == "-c" && i + 1 < argc) {
            threadCount = std::stoi(argv[++i]);
        } else if (std::string(argv[i]) == "-n" && i + 1 < argc) {
            requestCount = std::stoi(argv[++i]);
        } else {
            url = argv[i]; // Assume the last argument is the URL
        }
    }

    if (url == nullptr) {
        std::cerr << "Usage: " << argv[0] << " -c <ThreadCount> -n <RequestCount> <URL>" << std::endl;
        return 1;
    }

    // Initialize libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);

    auto start = std::chrono::steady_clock::now();

    ThreadPool pool(threadCount);  // Create a pool with specified number of threads

    // Submit tasks to the thread pool
    for (int i = 0; i < requestCount; ++i) {
        pool.enqueue([url, i] {
            incThreadsWorking();
            http_get(url);
            decThreadsWorking();
            std::cout << "Threads working: " << threads_working << std::endl;
        });
    }

    while(threads_working){
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    auto end = std::chrono::steady_clock::now();
    
    auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
    std::cout << "Elapsed time in seconds: " << duration.count() << " seconds." << std::endl;

    auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << "Elapsed time in milliseconds: " << duration_ms.count() << " ms." << std::endl;

    std::cout << "Requests per second: " << requestCount / duration.count() << "." << std::endl;

    // Cleanup global libcurl state
    curl_global_cleanup();

    return 0;
}