#include "mqtt_basic.hpp"
#include "mqtt_client.hpp"

#include <string>
#include <google/protobuf/message_lite.h>

namespace mqtt_dataio
{
    template <typename RT>
    class subscriber : public subscriber_basic
    {
    public:
        using DataCallback = std::function<void(const RT &)>;

    public:
        subscriber(const subscriber &) = delete;
        subscriber &operator=(const subscriber &) = delete;
        subscriber() = delete;

        subscriber(const std::string &name, DataCallback cb)
            : __m_name(name),
              __m_cb(cb)
        {
            mqtt_dataio::client::ins().add_suber(__m_name, this);
        }

        ~subscriber() override
        {
            mqtt_dataio::client::ins().rm_suber(__m_name);
        }

        virtual void on_message_arrival(const DataBuffer &buff) override
        {
            if (__m_cb) on_message_arrival_(buff);
        }

    private:
        template<typename U = RT, typename std::enable_if<!std::is_base_of<google::protobuf::MessageLite, U>::value, int>::type = 0>
        void on_message_arrival_(const DataBuffer& buff)
        {
            __m_cb(buff);
        }
        template<typename U = RT, typename std::enable_if<std::is_base_of<google::protobuf::MessageLite, U>::value, int>::type = 0>
        void on_message_arrival_(const DataBuffer& buff)
        {
            RT msg;
            msg.ParseFromArray(buff.data(), buff.size());
            __m_cb(msg);
        }

    private:
        std::string __m_name;
        DataCallback __m_cb;
    };
} // namespace mqtt_dataio
