#include <maps/wikimap/mapspro/libs/tasks/include/runner.h>

#include <mutex>
#include <signal.h>
#include <string.h>

namespace maps::wiki::tasks {

Runner::Runner()
{
    struct sigaction sa;
    ::memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &Runner::onStop;

    sigaction(SIGINT, &sa, 0);
    sigaction(SIGTERM, &sa, 0);
}

void Runner::run(
    std::function<void()> f,
    std::chrono::seconds sleepTime) const
{
    if (stopping()) {
        return;
    }

    std::mutex mutex;
    do {
        f();

        std::unique_lock lock(mutex);
        cv().wait_for(lock, sleepTime, [&] { return stopping(); });
    }
    while (!stopping());
}

void Runner::stop()
{
    stopping() = true;
    cv().notify_one();
}

void Runner::onStop(int)
{
    stop();
}

volatile bool& Runner::stopping()
{
    static volatile bool s_stopping = false;
    return s_stopping;
}

std::condition_variable& Runner::cv()
{
    static std::condition_variable s_cv;
    return s_cv;
}

} // namespace maps::wiki::tasks
