#pragma once
#include <atomic>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
#include <mw/http_server.hpp>
#include "server_config.hpp"
namespace nethack_mcp
{
class GameManager;
class McpServer;
struct GameRecord;
/// Serve shared MCP, landing, and live spectator routes.
class GameHttpServer : public mw::HTTPServer
{
public:
/// Construct the HTTP listener from the manager's server configuration.
GameHttpServer(GameManager& manager, McpServer& mcp);
/// Stop the listener before destroying the server.
~GameHttpServer();
GameHttpServer(const GameHttpServer&) = delete;
GameHttpServer& operator=(const GameHttpServer&) = delete;
/// Start serving and wait until the listener is ready.
bool startServer(std::string& error);
/// Stop the listener and wait for its serving thread.
void stopServer();
/// Report whether the HTTP listener is still serving.
bool running() const;
protected:
/// Register shared service, per-game, and static asset routes.
void setup() override;
private:
void serveStatic(std::string_view path, const Request& request,
Response& response);
void servePage(const Request& request, Response& response);
void serveGamePage(const Request& request, Response& response);
void serveScript(const Request& request, Response& response);
void serveStyle(const Request& request, Response& response);
void serveFont(const Request& request, Response& response);
void serveState(const Request& request, Response& response);
void serveHealth(const Request& request, Response& response);
void serveMetrics(const Request& request, Response& response);
void serveMcp(const Request& request, Response& response);
void rejectMcpStream(const Request& request, Response& response);
void rejectRequest(Response& response) const;
std::string recentPage();
GameManager& manager_;
McpServer& mcp_;
ServerConfig config_;
std::atomic<bool> started_ = false;
mutable std::atomic<std::size_t> active_requests_ = 0;
mutable std::atomic<std::uint64_t> request_count_ = 0;
mutable std::atomic<std::uint64_t> request_latency_total_us_ = 0;
};
} // namespace nethack_mcp