#ifndef SERVER_H
#define SERVER_H

#include "communicate.hpp"
#include "handle.h"
#include "jsondata.h"
#include "zapi.h"
#include <asio.hpp>
#include <mutex>
#include <unordered_map>

constexpr size_t g_BuffSize = 1024 * 10;
struct ClientCache {
    std::array<char, g_BuffSize> tmp_buf_{};
    CMutBuffer buffer_{};
};

class Server
{
public:
    Server(asio::io_context& io_context, short port);
    ~Server();

public:
    void start();
    void stop();

public:
    void set_worker(std::shared_ptr<COpenAI> worker, std::shared_ptr<CJsonOper> json);
    void set_token(long tokens);
private:
    void do_accept();
    void th_client(const std::shared_ptr<asio::ip::tcp::socket>& socket, const std::string& client_key);

    std::string post_data(const std::string& data);
    bool send_frame(const std::shared_ptr<asio::ip::tcp::socket>& socket, FrameData& data);
    void print_exception(const std::exception& e);

private:
    asio::io_context& io_context_;
    asio::ip::tcp::acceptor acceptor_;

    std::shared_ptr<COpenAI> worker_{};
    std::shared_ptr<CJsonOper> json_{};
    std::mutex ask_mutex_;
    std::mutex cli_mutex_;
    std::unordered_map<std::string, std::thread> clients_;
    std::map<std::string, std::shared_ptr<ClientCache>> client_map_;
    CMutBuffer buffer_{};
    short port_;
    long tokens_{};
    long use_tokens_{};
};

#endif