/**
 * \file main.cpp
 * \brief Univerxel game
 * \author Maelys Bois
 * \version 0.0.1
 *
 * Univerxel main program.
 */

#include "client/Client.hpp"
#include "server/Server.hpp"
#include "core/config.hpp"
#include "core/utils/tracy.hpp"
#include "version.h"

/// Entry point
int main(int argc, char *argv[]){
    LOG("Univerxel " << UNIVERXEL_VERSION);

#if TRACY_ENABLE
    LOG("Profiling !");
#endif

    auto options = config::options(argc > 1 ? argv[1] : config::DEFAULT_FILE);
    options.save();

    std::optional<Server> server;
    if (options.hasServer())
        server.emplace(options.getServer());
    std::optional<Client> client;
    if (options.hasClient())
        client.emplace(options.getClient());

    const auto serverTask = [&] {
#if TRACY_ENABLE
        tracy::SetThreadName("Server");
#endif
        server.value().run();
    };
    const auto clientTask = [&](server_handle* const handle) {
#if TRACY_ENABLE
        tracy::SetThreadName("Client");
#endif
        client.value().run(handle);
    };

    if (server.has_value()) {
        if (client.has_value()) {
            auto serverThread = std::thread(serverTask);

            clientTask(server.value().getHandle());

            if(serverThread.joinable())
                serverThread.join();
        } else {
            serverTask();
        }
    } else {
        if (client.has_value()) {
            clientTask(nullptr);
        } else  {
            options.save();
            FATAL("Nothing to start");
        }
    }

    options.save();

    return 0;
}