#ifndef __ONLINE_HPP__
#define __ONLINE_HPP__
#include "util.hpp"
#include <mutex>
#include <unordered_map>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

/*在线用户管理模块 -- 用于管理在游戏大厅以及游戏房间中的用户，建立用户id与websocket长连接的对应关系*/
class online_manager {
public:
    online_manager() { LOG(DEBUG, "在线用户管理模块初始化完毕"); }
    ~online_manager() { LOG(DEBUG, "在线用户管理模块已被销毁"); }

    /*用户进入游戏大厅(此时用户websocket长连接已建立好)*/
    void enter_game_hall(uint64_t uid, wsserver_t::connection_ptr conn) {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user[uid] = conn;
    }
    /*用户进入游戏房间*/
    void enter_game_room(uint64_t uid, wsserver_t::connection_ptr conn) {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user[uid] = conn;
    }

    /*用户离开游戏大厅(websocket长连接断开时)*/
    void exit_game_hall(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user.erase(uid);
    }

    /*用户对战结束离开游戏房间回到游戏大厅*/
    void exit_game_room(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user.erase(uid);
    }

    /*判断当前用户是否在游戏大厅*/
    bool is_in_game_hall(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_user.find(uid);
        if(it == _hall_user.end()) return false;
        return true;
    }

    /*判断当前用户是否在游戏房间*/
    bool is_in_game_room(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_user.find(uid);
        if(it == _room_user.end()) return false;
        return true;
    }

    /*通过用户id获取游戏大厅用户的通信连接*/
    wsserver_t::connection_ptr get_conn_from_hall(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_user.find(uid);
        if(it == _hall_user.end()) return nullptr;
        return _hall_user[uid];
    }

    /*通过用户id获取游戏房间用户的通信连接*/
    wsserver_t::connection_ptr get_conn_from_room(uint64_t uid) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_user.find(uid);
        if(it == _room_user.end()) return nullptr;
        return _room_user[uid];
    }
private:
    std::mutex _mutex;  // 解决多线程模式下的线程安全问题
    std::unordered_map<uint64_t, wsserver_t::connection_ptr> _hall_user;  // 建立游戏大厅用户id与通信连接之间的关系
    std::unordered_map<uint64_t, wsserver_t::connection_ptr> _room_user;  // 建立游戏房间用户id与通信连接之间的关系
};
#endif