#pragma once

#include "hiredis/adapters/qt.h"
#include "hiredis/async.h"
#include "hiredis/hiredis.h"
#include <QObject>
#include <QDebug>
#include <QJsonObject>
#include <QJsonDocument>
#include "RedisClient_global.h"

class REDISCLIENT_EXPORT RedisClient : public QObject
{
    Q_OBJECT
public:
    explicit RedisClient(QObject *parent = 0);
    ~RedisClient();

public slots:
    void start();
    void conn();
    bool hset(const QString& m, const QString& k, const QString& v);
    QString hget(const QString& m, const QString& k);
    bool set(const QString& k, const QString& v);
    bool setb(const QString& k,const QByteArray &v);
    QString get(const QString& k);
    QByteArray getb(const QString& k);
    QStringList hkeys(const QString& k);
    QStringList hvals(const QString& k);
    QHash<QString, QString> hgetall(const QString& k);
    bool rpush(const QString& lData, const QString& js);                  //向队列尾部加入字符串数据
    bool rpushb(const QString& lData, const QByteArray& ba);              //向队列尾部加入二进制数据
    QString lpop(const QString& lData);
    QString blpop(const QString& lData, quint32 timeout);          //同步阻塞一定时间返回数据
    bool blpop(const QString& lData, redisCallbackFn *fn);         //阻塞从队列头部获取最早数据
    bool publish(const QString& ch, const QString& js);
    bool publishb(const QString& ch, const QByteArray& ba);
    bool expire(const QString& k,int sec);
    void subscribe(const QString& ch, redisCallbackFn *fn, void* data = nullptr);        // 订阅
    void psubscribe(const QString& ch, redisCallbackFn *fn, void* priData = nullptr);       // 订阅：模式匹配

private:
    //QString ip = "192.168.9.56";
    QString ip = "127.0.0.1";
    quint16 port = 16379;
    QString auth = "<LanPeng&&CeKong>";

    bool redisOk = false;               //redis全局状态，操作出错时置为false, redis线程内会自动重连
    redisContext *rc;                   //同步连接
    redisAsyncContext *rac = nullptr;   //异步连接
    RedisQtAdapter adapter;             //异步事件驱动适配器

public:
    void Setup(const QString& addr, uint port, const QString& password);
};
