#include #include #include #include #include #include "config.hpp" #include "database.hpp" #include "server.hpp" std::atomic stopServer{false}; void signalHandler(int signal) { if (signal == SIGINT || signal == SIGTERM) { std::cout << "\nReceived shutdown signal. Stopping server..." << std::endl; stopServer = true; } } int main(int argc, char* argv[]) { try { std::string configFile = "config.json"; bool debug = false; bool configFileSpecified = false; for (int i = 1; i < argc; ++i) { const std::string argument = argv[i]; if (argument == "--debug") { debug = true; } else if (argument.starts_with("--")) { throw std::invalid_argument("Unknown option: " + argument); } else if (configFileSpecified) { throw std::invalid_argument("Only one configuration file can be specified"); } else { configFile = argument; configFileSpecified = true; } } if (debug) { std::cout << "[debug] Debug mode enabled" << std::endl; std::cout << "[debug] Configuration file: " << configFile << std::endl; } std::cout << "Loading configuration from: " << configFile << std::endl; AppConfig config = AppConfig::loadFromFile(configFile); if (debug) { std::cout << "[debug] Server configuration: address=" << config.server.address << ", port=" << config.server.port << ", threads=" << config.server.threads << std::endl; std::cout << "[debug] Database configuration: host=" << config.database.host << ", port=" << config.database.port << ", dbname=" << config.database.dbname << ", user=" << config.database.user << ", password=" << (config.database.password.empty() ? "not set" : "set") << std::endl; std::cout << "[debug] Initializing database connection pool" << std::endl; } std::cout << "Connecting to database..." << std::endl; auto db = std::make_shared(config.database, 2, debug); std::cout << "Database connected successfully!" << std::endl; if (debug) { std::cout << "[debug] Creating HTTP server" << std::endl; } Server server( config.server.address, config.server.port, config.server.threads, db ); std::signal(SIGINT, signalHandler); std::signal(SIGTERM, signalHandler); if (debug) { std::cout << "[debug] SIGINT and SIGTERM handlers installed" << std::endl; } std::cout << "Server is running on " << config.server.address << ":" << config.server.port << " with " << config.server.threads << " threads" << std::endl; std::cout << "Press Ctrl+C to stop" << std::endl; std::thread serverThread([&server]() { server.run(); }); if (debug) { std::cout << "[debug] Server thread started" << std::endl; } while (!stopServer) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if (debug) { std::cout << "[debug] Stopping I/O context" << std::endl; } std::cout << "Stopping server..." << std::endl; server.stop(); serverThread.join(); if (debug) { std::cout << "[debug] Server thread joined" << std::endl; } std::cout << "Server stopped successfully!" << std::endl; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } return 0; }