#ifndef SHAREDSTATE_H
#define SHAREDSTATE_H

#include "router.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/smart_ptr.hpp>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_set>

class HttpSession;
class WebSocketSession;

// Represents the shared server state
class SharedState : public std::enable_shared_from_this<SharedState> {

    // This mutex synchronizes all access to sessions_
    std::mutex mutex_;

    // Keep a list of all the connected clients
    std::unordered_set<WebSocketSession *> sessions_;

public:
    using Request = boost::beast::http::request<boost::beast::http::string_body>;
    using Handler = std::function<void(HttpSession &, const Request &, const boost::urls::matches &)>;
    SharedState(boost::asio::io_context &ioContext);

    const Handler *find(boost::urls::segments_encoded_view path, boost::urls::matches_base &matches) const noexcept;

    void join(WebSocketSession *session);
    void leave(WebSocketSession *session);

    /**
     * @brief Broadcast a message to all websocket client sessions
     */
    void send(std::string message);

private:
    boost::asio::io_context &m_ioContext;
    std::shared_ptr<boost::urls::router<Handler>> m_router;
    std::string m_docRoot;
    std::string m_galleryRoot = "/root/photos";
    std::string m_fileRoot;
};

using SharedStatePtr = std::shared_ptr<SharedState>;

#endif // SHAREDSTATE_H
