BareGit
#include <filesystem>
#include <iostream>
#include <string>
#include <string_view>
#include <thread>
#include <utility>

#include "app.h"
#include "data_source_sqlite.h"
#include "scheduler.h"

namespace
{

void printUsage(std::ostream& output)
{
    output << "Usage: probius FILE\n";
}

}

// Entry point for the status tracker service.
int main(int argc, char** argv)
{
    if(argc == 2 && std::string_view(argv[1]) == "--help")
    {
        printUsage(std::cout);
        return 0;
    }
    if(argc != 2)
    {
        printUsage(std::cerr);
        return 2;
    }
    auto configuration = Configuration::fromYaml(
        std::filesystem::path(argv[1]));
    if(!configuration)
    {
        std::cerr << configuration.error().msg() << '\n';
        return 1;
    }
    auto data_source = DataSourceSqlite::open(configuration->database_path);
    if(!data_source)
    {
        std::cerr << data_source.error().msg() << '\n';
        return 1;
    }
    auto scheduler = Scheduler::create(*configuration, **data_source);
    if(!scheduler)
    {
        std::cerr << scheduler.error().msg() << '\n';
        return 1;
    }
    mw::HTTPServer::ListenAddress listen =
        mw::IPSocketInfo{"127.0.0.1", 8080};
    std::string listen_description = "http://127.0.0.1:8080";
    if(!configuration->unix_socket.empty())
    {
        mw::SocketFileInfo socket(configuration->unix_socket);
        socket.permission = configuration->socket_permission;
        listen = std::move(socket);
        listen_description = "Unix socket " + configuration->unix_socket;
    }
    App app(listen,
            std::move(*configuration), **data_source);
    auto started = app.start();
    if(!started)
    {
        std::cerr << started.error().msg() << '\n';
        return 1;
    }
    std::jthread scheduler_thread(
        [scheduler = std::move(*scheduler), &app](std::stop_token stop) {
            auto result = scheduler->run(stop);
            if(!result)
            {
                std::cerr << "Scheduler stopped: "
                          << result.error().msg() << '\n';
                app.stop();
            }
        });
    std::cout << "Probius listening on " << listen_description << '\n'
              << std::flush;
    app.wait();
    scheduler_thread.request_stop();
    return 0;
}