#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;
}