/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#ifndef TANGO_SERVER_POLLOBJ_H
#define TANGO_SERVER_POLLOBJ_H

#include <tango/server/PollRing.h>
#include <tango/server/tango_clock.h>

namespace Tango
{

//=============================================================================
//
//            The PollObj class
//
// description :    Class to store all the necessary information which will
//            be stored and returned to client on request
//
//            This class is protected against concurrent access by a
//            omni_mutex. We use the Thread-Safe interface pattern
//            to avoid "self-deadlock". This is why several methods
//            are splitted in two: One method called "meth" and
//            another one called "meth_i" (which is also sometimes
//            public !!)
//
//=============================================================================

class PollObj : public omni_mutex
{
  public:
    PollObj(DeviceImpl *, PollObjType, const std::string &, PollClock::duration);
    PollObj(DeviceImpl *, PollObjType, const std::string &, PollClock::duration, long);

    void insert_data(CORBA::Any *, PollClock::time_point, PollClock::duration);
    void insert_data(Tango::AttributeValueList *, PollClock::time_point, PollClock::duration);
    void insert_data(Tango::AttributeValueList_3 *, PollClock::time_point, PollClock::duration);
    void insert_data(Tango::AttributeValueList_4 *, PollClock::time_point, PollClock::duration);
    void insert_data(Tango::AttributeValueList_5 *, PollClock::time_point, PollClock::duration);
    void insert_except(Tango::DevFailed *, PollClock::time_point, PollClock::duration);

    PollClock::duration get_authorized_delta()
    {
        return max_delta_t;
    }

    void update_upd(PollClock::duration);

    CORBA::Any *get_last_cmd_result();
    Tango::AttributeValue &get_last_attr_value(bool);
    Tango::AttributeValue_3 &get_last_attr_value_3(bool);
    Tango::AttributeValue_4 &get_last_attr_value_4(bool);
    Tango::AttributeValue_5 &get_last_attr_value_5(bool);

    bool is_ring_empty()
    {
        omni_mutex_lock sync(*this);
        return is_ring_empty_i();
    }

    bool is_ring_empty_i()
    {
        return ring.is_empty();
    }

    PollClock::duration get_upd()
    {
        omni_mutex_lock sync(*this);
        return get_upd_i();
    }

    PollClock::duration get_upd_i()
    {
        return upd;
    }

    std::string &get_name()
    {
        omni_mutex_lock sync(*this);
        return get_name_i();
    }

    std::string &get_name_i()
    {
        return name;
    }

    PollClock::duration get_needed_time()
    {
        omni_mutex_lock sync(*this);
        return get_needed_time_i();
    }

    PollClock::duration get_needed_time_i()
    {
        return needed_time;
    }

    PollObjType get_type()
    {
        omni_mutex_lock sync(*this);
        return get_type_i();
    }

    PollObjType get_type_i()
    {
        return type;
    }

    PollClock::time_point get_last_insert_date()
    {
        omni_mutex_lock sync(*this);
        return get_last_insert_date_i();
    }

    PollClock::time_point get_last_insert_date_i();

    bool is_last_an_error()
    {
        omni_mutex_lock sync(*this);
        return is_last_an_error_i();
    }

    bool is_last_an_error_i()
    {
        return ring.is_last_an_error();
    }

    bool is_last_an_error_i_3()
    {
        if(type == POLL_CMD)
        {
            return ring.is_last_cmd_an_error();
        }
        else
        {
            return ring.is_last_attr_an_error();
        }
    }

    Tango::DevFailed *get_last_except()
    {
        omni_mutex_lock sync(*this);
        return get_last_except_i();
    }

    Tango::DevFailed *get_last_except_i()
    {
        return ring.get_last_except();
    }

    Tango::DevErrorList &get_last_attr_error_i()
    {
        return ring.get_last_attr_error();
    }

    std::vector<PollClock::duration> get_delta_t(long nb)
    {
        omni_mutex_lock sync(*this);
        return get_delta_t_i(nb);
    }

    std::vector<PollClock::duration> get_delta_t_i(long nb)
    {
        return ring.get_delta_t(nb);
    }

    long get_elt_nb_in_buffer()
    {
        omni_mutex_lock sync(*this);
        return get_elt_nb_in_buffer_i();
    }

    long get_elt_nb_in_buffer_i()
    {
        return ring.get_nb_elt();
    }

    void get_cmd_history(long, Tango::DevCmdHistoryList *);
    void get_cmd_history(long, Tango::DevCmdHistory_4 *, Tango::CmdArgType &);

    void get_attr_history(long, Tango::DevAttrHistoryList *, long);
    void get_attr_history(long, Tango::DevAttrHistoryList_3 *, long);
    void get_attr_history(long, Tango::DevAttrHistory_4 *, long, AttrDataFormat);
    void get_attr_history(long, Tango::DevAttrHistory_5 *, long, AttrDataFormat);

    void get_attr_history_43(long n, Tango::DevAttrHistoryList_3 *ptr, long type);

    bool is_fwd_att()
    {
        return fwd;
    }

  protected:
    DeviceImpl *dev;
    PollObjType type;
    std::string name;
    PollClock::duration upd;
    PollClock::duration needed_time;
    PollClock::duration max_delta_t;
    PollRing ring;
    bool fwd;
};

inline bool operator<(const PollObj &, const PollObj &)
{
    return true;
}

inline bool operator==(const PollObj &, const PollObj &)
{
    return true;
}

} // namespace Tango

#endif /* _POLLOBJ_ */
