#pragma once
#include <string_view>

#include "Psc_Cpp_Core/Base/global_include.h"
#include "Psc_Cpp_Core/socket/ByteOrder.h"

#include <drogon/WebSocketConnection.h>
#include <drogon/WebSocketController.h>



class WebSocket_Manager {
public:
  using Message_Handler = std::function<void(const drogon::WebSocketConnectionPtr &conn, std::string &&message, const drogon::WebSocketMessageType &type)>;
  using Close_Handler = std::function<void(const drogon::WebSocketConnectionPtr &conn)>;
  explicit WebSocket_Manager(std::string_view path);
  ~WebSocket_Manager() = default;
  void remove(const drogon::WebSocketConnectionPtr &conn);
  void add(const drogon::WebSocketConnectionPtr &conn);
  void push_data(const char *buf, uint64_t len);
  void set_message_handler(Message_Handler handler);
  void set_close_handler(Close_Handler handler);
  void handle_message(const drogon::WebSocketConnectionPtr &conn, std::string &&message, const drogon::WebSocketMessageType &type);
  void handle_close(const drogon::WebSocketConnectionPtr &conn);
  size_t get_websocket_connect_num();
  std::string path;
protected:
  std::mutex                                 mtx;
  std::unordered_set<drogon::WebSocketConnectionPtr> connections;
  Message_Handler message_handler;
  Close_Handler close_handler;
};


class Ws_Mgr : public Psc::Singleton<Ws_Mgr> {
public:
    std::shared_ptr<WebSocket_Manager> register_ws(std::string_view path);
    std::shared_ptr<WebSocket_Manager> get_ws(std::string_view path);
    std::map<std::string, std::shared_ptr<WebSocket_Manager>> map;
};




