/*
 * SPDX-FileCopyrightText: 2025 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#ifndef TANGO_CLIENT_ASYNREQ_H
#define TANGO_CLIENT_ASYNREQ_H

#include <tango/client/TgRequest.h>
#include <tango/client/UniqIdent.h>

#include <map>
#include <vector>

namespace Tango
{
class AsynReq : public omni_mutex
{
  public:
    AsynReq(UniqIdent *ptr) :
        ui_ptr(ptr),
        cond(this)
    {
    }

    ~AsynReq()
    {
        delete ui_ptr;
    }

    TgRequest &get_request(long);
    TgRequest &get_request(CORBA::Request_ptr);
    TgRequest *get_request(Tango::Connection *);

    long store_request(CORBA::Request_ptr, TgRequest::ReqType);
    void store_request(CORBA::Request_ptr, CallBack *, Connection *, TgRequest::ReqType);

    void remove_request(long);
    void remove_request(Connection *, CORBA::Request_ptr);

    size_t get_request_nb()
    {
        omni_mutex_lock sync(*this);
        return asyn_poll_req_table.size();
    }

    size_t get_cb_request_nb()
    {
        omni_mutex_lock sync(*this);
        return cb_req_table.size();
    }

    size_t get_cb_request_nb_i()
    {
        return cb_req_table.size();
    }

    void mark_as_arrived(CORBA::Request_ptr req);

    std::multimap<Connection *, TgRequest> &get_cb_dev_table()
    {
        return cb_dev_table;
    }

    void mark_as_cancelled(long);
    void mark_all_polling_as_cancelled();

    // Expects: Calling thread to have locked *this
    void wait()
    {
        cond.wait();
    }

    void signal()
    {
        omni_mutex_lock sync(*this);
        cond.signal();
    }

    bool is_shutdown() const
    {
        omni_mutex_lock sync(*const_cast<AsynReq *>(this));
        return shutdown_requested;
    }

    void request_shutdown()
    {
        omni_mutex_lock sync(*this);
        shutdown_requested = true;
        cond.broadcast();
    }

    void start_thread()
    {
        omni_mutex_lock sync(*this);
        shutdown_requested = false;
    }

  protected:
    std::map<long, TgRequest> asyn_poll_req_table;
    UniqIdent *ui_ptr;

    std::multimap<Connection *, TgRequest> cb_dev_table;
    std::map<CORBA::Request_ptr, TgRequest> cb_req_table;

    std::vector<long> cancelled_request;

  private:
    omni_condition cond;
    bool remove_cancelled_request(long);
    bool shutdown_requested{false};
};
} // namespace Tango
#endif
