#include "Server.hpp"
#include "world/StandaloneUniverse.hpp"
#ifndef STANDALONE
#include "world/SharedUniverse.hpp"
#endif
#include <signal.h>
#include <chrono>

Server::Server(config::server::options& options): options(options), localHandle(options.allowLocal ? new server_handle() : nullptr) { }
Server::~Server() { }

const auto TPS = 10;

static bool running = true;
void handle_signal(int) { running = false; }

void Server::run() {
    universe = [&]() -> std::unique_ptr<world::server::Universe> {
#ifndef STANDALONE
        if(options.allowLocal)
            return std::make_unique<world::server::SharedUniverse>(options.world, localHandle);
#endif

        return std::make_unique<world::server::StandaloneUniverse>(options.world);
    }();

    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);

    auto lastTick = std::chrono::steady_clock::now();
    while(running && (localHandle == nullptr || localHandle->running)) {
        FrameMarkStart("Server");
        auto startTick = std::chrono::steady_clock::now();
        const std::chrono::duration<float, std::ratio<1>> deltaTime = startTick - lastTick;
        universe->update(deltaTime.count());
        FrameMarkEnd("Server");
        while (std::chrono::steady_clock::now() < startTick + std::chrono::milliseconds(1000 / TPS)) {
            universe->pull();
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
        lastTick = startTick;
    }
}