BareGit
#pragma once

#include <chrono>
#include <cstddef>
#include <filesystem>
#include <optional>
#include <string>

namespace nethack_mcp
{

/// Startup-only listener settings, limits, and public URL policy.
struct ServerConfig
{
    /// Network address or Unix domain socket path used by the HTTP listener.
    std::string listen_address = "127.0.0.1";
    /// TCP listener port; ignored when listening on a Unix socket.
    int port = 8765;
    /// Optional permission bits for a Unix domain socket file.
    std::optional<unsigned int> listen_socket_permission;
    /// Private per-game worker files, normally on temporary storage.
    std::filesystem::path data_root;
    /// Persistent SQLite database path, outside temporary storage.
    std::filesystem::path database_path;
    /// Directory containing the NetHack runtime data files.
    std::filesystem::path runtime_directory;
    /// Canonical public URL used in MCP results and viewer links.
    std::string public_base_url;
    /// Maximum number of active and concurrently starting games.
    std::size_t max_active_games = 8;
    /// Game creation quota for each client address.
    std::size_t new_games_per_client = 8;
    /// Time window used for the per-client creation quota.
    std::chrono::seconds new_game_rate_window{3600};
    /// Bad control-token attempts allowed for each client address.
    std::size_t control_failures_per_client = 10;
    /// Time window used for the bad-token limit.
    std::chrono::seconds control_failure_window{60};
    /// Upper bound on client-address entries kept by rate limiters.
    std::size_t max_rate_limit_clients = 4096;
    /// Maximum number of simultaneous HTTP handler workers.
    std::size_t max_concurrent_requests = 64;
    /// Maximum active plus queued HTTP connection tasks.
    std::size_t max_open_connections = 128;
    /// End a game after this long without an accepted agent call.
    std::chrono::seconds idle_timeout{600};
    /// Maximum time from accepted creation to game termination.
    std::chrono::seconds max_game_duration{86400};
    /// Fallback maintenance cadence for expiry and cleanup work.
    std::chrono::seconds lifecycle_sweep_interval{15};
    /// Maximum accepted MCP request body size in bytes.
    std::size_t max_mcp_body_bytes = 1024U * 1024U;
    /// Maximum diagnostic output bytes logged for one worker.
    std::size_t max_worker_output_bytes = 1024U * 1024U;
    /// Maximum accepted character name length in bytes.
    std::size_t max_character_name_bytes = 30;
    /// Maximum accepted model slug length in bytes.
    std::size_t max_model_slug_bytes = 128;
};

} // namespace nethack_mcp