#ifndef C7F35237_1097_46F2_9573_490355317C24
#define C7F35237_1097_46F2_9573_490355317C24

#include <mesytec-mnode/mnode_nng.h>

namespace mesytec::mnode::nng
{

struct IWork
{
    virtual ~IWork() = default;
    virtual void work() = 0;
};

struct IReqWork: public IWork
{
    virtual nng::unique_msg make_request() = 0;
    virtual void handle_reply(nng::unique_msg &&request, nng::unique_msg &&reply) = 0;
};

struct IRepWork: public IWork
{
    virtual nng::unique_msg handle_request(nng::unique_msg &&request) = 0;
};

class AsyncReqWork: public IReqWork
{
  public:
    explicit AsyncReqWork(nng_socket socket);
    ~AsyncReqWork() override;
    void work() override;

  private:
    enum State { INIT, RECEIVE, SEND, };
    State state = INIT;
    nng_socket socket;
    nng_aio *aio = nullptr;
    nng_ctx ctx;
    nng::unique_msg request_;
};

class AsyncRepWork: public IRepWork
{
  public:
    explicit AsyncRepWork(nng_socket socket);
    ~AsyncRepWork() override;
    void work() override;

  private:
    enum State { INIT, RECEIVE, SEND, };
    State state = INIT;
    nng_socket socket;
    nng_aio *aio = nullptr;
    nng_ctx ctx;
};

} // namespace mesytec::mnode::nng

#endif /* C7F35237_1097_46F2_9573_490355317C24 */
