#include <iostream>
#include <fstream>
#include <string>
#include <curl/curl.h>
#include <thread>
#include <chrono>
#include <windows.h>
#include "nlohmann/json.hpp"  // Ensure json.hpp is correctly located

using json = nlohmann::json;

std::size_t writeCallback(void* contents, std::size_t size, std::size_t nmemb, std::string* s) {
    size_t newLength = size * nmemb;
    try {
        s->append((char*)contents, newLength);
    }
    catch (std::bad_alloc& e) {
        return 0;
    }
    return newLength;
}

bool performRequest(const std::string& url, const std::string& savePath) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        std::cerr << "Curl initialization failed!" << std::endl;
        return false;
    }

    std::string response_string;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        curl_easy_cleanup(curl);
        return false;
    }

    std::ofstream outFile(savePath);
    if (!outFile.is_open()) {
        std::cerr << "Failed to open " << savePath << std::endl;
        curl_easy_cleanup(curl);
        return false;
    }

    outFile << response_string;
    outFile.close();
    curl_easy_cleanup(curl);
    return true;
}

json loadConfig(const std::string& configPath) {
    std::ifstream configFile(configPath);
    json configJson;
    if (!configFile.is_open()) {
        std::cerr << "Unable to open config file" << std::endl;
        std::exit(EXIT_FAILURE);
    }
    configFile >> configJson;
    return configJson;
}

void launchAndWait(const std::string& executablePath) {
    STARTUPINFOA si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi;

    if (!CreateProcessA(NULL, const_cast<char*>(executablePath.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        std::cerr << "Failed to start process. Error: " << GetLastError() << std::endl;
        std::exit(EXIT_FAILURE);
    }

    std::cout << "External application launched." << std::endl;
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

int main() {
    ::ShowWindow(::GetConsoleWindow(), SW_HIDE);
    std::string configFilePath = "config.json";
    auto config = loadConfig(configFilePath);
    std::string url = config["url"];
    std::string jsonPath = "Modules/coop_test/lua/request.json";
    int interval = config["interval"];
    std::string launchPath = "mb_warband_wse2.exe --module coop_test";

    std::thread otherApp(launchAndWait, launchPath);
    std::thread requestThread([&] {
        while (otherApp.joinable()) {
            if (!performRequest(url, jsonPath)) {
                std::cerr << "Error performing HTTP request." << std::endl;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        }
        });

    // Wait for the external application to finish
    otherApp.join();
    requestThread.join();
    std::cout << "External application has closed.Exiting background process." << std::endl;
    return 0;
}

Add intend to the output.json