#ifndef _TenkinetThread_h__
#define _TenkinetThread_h__

#include <QMutex>
#include <QVector>

#include "DaemonThread.h"
#include "TenkinetProvider.h"
#include "ntp.h"
#include "tenkinet.h"

class TenkinetThread : public DaemonThread {

    Q_OBJECT

  public:
    // Singleton instance
    static TenkinetThread &instance() {
        static TenkinetThread instance;
        return instance;
    }

    // Disable copy constructor and assignment operator
    // Required to enforce singleton pattern
    TenkinetThread(TenkinetThread const &) = delete;
    void operator=(TenkinetThread const &) = delete;

    virtual ~TenkinetThread();

    virtual void run();
    virtual void shutdown();

    bool add(TenkinetProvider *provider);
    bool remove(TenkinetProvider *provider);
    void connectClient(TenkinetProvider *provider);
    void disconnectClient(TenkinetProvider *provider);
    void refresh(TenkinetProvider *provider);
    void setSubscribed(TenkinetProvider *provider, bool subscribed);
    void setPollInterval(TenkinetProvider *provider, unsigned int ms);

  private:
    static QMutex mutex;
    static List devices;

    enum State {
        INIT,
        RUNNING,
        SHUTDOWN,
    };

    State state = INIT;
    TenkinetCallbacks callbacks;
    select_helper_data seldata;

    QVector<void *> commands;

    TenkinetThread();

    int processCommands();

    // Tenkinet callbacks
    static void connectionCallback(TenkinetClient client, int status, void *user_data);
    static void listCallback(TenkinetClient client, void *user_data);
    static void dataCallback(TenkinetClient client, int64_t timestamp, void *user_data);
    static void deviceStatusCallback(TenkinetClient client, int64_t timestamp, Device *device, void *user_data);

    // NTP callback
    static void ntpCallback(NTP_Client ntpClient, NTP_Result *result, void *user_data);
};

#endif
