/*
 * server/server.h — VoiceCat server entry point.
 *
 * Design: docs/architecture.md §5. Headless process: TLS control listener,
 * session registry, text relay, SQLite persistence. Zero-config first-run.
 */
#ifndef VOICECAT_SERVER_SERVER_H
#define VOICECAT_SERVER_SERVER_H

#include <cstdint>
#include <functional>
#include <mutex>
#include <string>

namespace voicecat::server {

struct Config {
    std::string server_name  = "VoiceCat Server";
    std::string data_dir     = "voicecat-data";
    uint16_t    bind_port    = 8384;   // 0 = let OS pick (useful for tests)
    uint16_t    media_port   = 0;      // M2 UDP media; 0 = follow bind_port (or OS-pick if that's 0)
    bool        allow_guests = true;
    // Called with the actual bound TCP port once the acceptor is ready.
    std::function<void(uint16_t)> on_ready;
    // Called with the actual bound UDP media port once the relay is ready.
    std::function<void(uint16_t)> on_media_ready;

    // Keepalive reaper (docs/protocol.md §7): sweep every reaper_sweep_ms and drop any
    // session whose last inbound TCP/UDP activity is older than reaper_timeout_ms. Defaults
    // match the doc: 15s sweep, 45s timeout (3 missed 15s pongs). Set reaper_timeout_ms = 0
    // to disable the reaper entirely (useful for tests that don't want it).
    int64_t reaper_timeout_ms = 45000;
    int64_t reaper_sweep_ms   = 15000;
};

class Server {
   public:
    explicit Server(Config cfg) : cfg_(std::move(cfg)) {}

    // Block until the server shuts down. Returns process exit code.
    int run();

    // Thread-safe stop: unblocks run() from any thread. No-op if not running.
    void stop();

   private:
    Config              cfg_;
    std::mutex          stop_mutex_;
    std::function<void()> stop_fn_;
};

}  // namespace voicecat::server

#endif  // VOICECAT_SERVER_SERVER_H
