#include "MQTTBase.h"

#include <QDebug>


#include "qmqtt_message.h"


MQTTBase::MQTTBase(QObject* parent) : QObject(parent)
{
    /* 获取日志 */
    m_logger = spdlog::get("MQTT");
    if(m_logger == nullptr)
    {
        SPDLOG_ERROR("获取MQTT logger 失败!");
        exit(-1);
    }

    /* 连接信号和槽 */
    connect(&m_client,SIGNAL(connected()),this,SLOT(do_connected()));
    connect(&m_client,SIGNAL(disconnected()),this,SLOT(do_disconnect()));
    connect(&m_client,SIGNAL(error(QMQTT::ClientError)),this,SLOT(do_error(QMQTT::ClientError)));
    connect(&m_client,SIGNAL(subscribed(QString,quint8)),this,SLOT(do_subscribed(QString, quint8)));

    connect(&m_client,SIGNAL(received(QMQTT::Message)),this,SLOT(do_received(QMQTT::Message)));
}

/* 设置地址 */
void MQTTBase::setIPAndPort(const QString& IP, int port)
{
    m_mqttIP = IP;
    m_mqttPort = port;
    QHostAddress addr = QHostAddress(IP);
    m_client.setHost(addr);
    m_client.setPort(port);
}

/* 设置订阅 */
void MQTTBase::addSubcribe(const QString& topic, int qos)
{
    if(qos > 2)
    {
        SPDLOG_LOGGER_ERROR(m_logger,"QoS值不合法:{}", qos);
        return;
    }
    if(m_isConnected)
    {
        /* 已连接到MQTT,之前添加的主题已经订阅,现在添加的也直接添加订阅 */
        m_client.subscribe(topic, qos);
        m_mapTopic.insert(topic, qos);
    }else 
    {
        /* 还未连接到MQTT,直接加入到订阅列表 */
        m_mapTopic.insert(topic, qos);
    }
}

/* 设置自动重连 */
void MQTTBase::setAutoReconnect(bool isAuto)
{
    m_client.setAutoReconnect(isAuto);
}

/* 连接到服务器 */
void MQTTBase::connectToServer()
{
    m_client.connectToHost();
}

/* 发送消息 */
void MQTTBase::sendMessage(const QString& topic, const QByteArray& message, int qos)
{
    if(m_isConnected == false)
    {
        SPDLOG_LOGGER_ERROR(m_logger,"MQTT未连接到服务器,发送消息失败");
        return;
    }
    QMQTT::Message msg(0, topic, message, qos);
    auto ret = m_client.publish(msg);
    if(ret != 0)
    {
        SPDLOG_LOGGER_ERROR(m_logger,"发送消息失败:{}, 错误代码:{}", topic.toStdString(), ret);
    }
}


/* 连接成功 */
void MQTTBase::do_connected()
{
    SPDLOG_LOGGER_INFO(m_logger,"MQTT IP:{} ,Port:{} 连接成功!", m_mqttIP.toStdString(), m_mqttPort);
    m_isConnected = true;
    /* 订阅所有的主题 */
    for(auto& it : m_mapTopic.keys())
    {
        auto qos = m_mapTopic.value(it);
        m_client.subscribe(it, qos);
    }
}

/* 断开连接 */
void MQTTBase::do_disconnect()
{
    SPDLOG_LOGGER_INFO(m_logger,"断开连接!");
}

/* 错误 */
void MQTTBase::do_error(const QMQTT::ClientError error)
{
    SPDLOG_LOGGER_ERROR(m_logger,"错误:{}", (int)error);
}

/* 订阅成功 */
void MQTTBase::do_subscribed(const QString& topic, const quint8 qos)
{
    SPDLOG_LOGGER_INFO(m_logger,"订阅:{}, QoS:{} 成功", topic.toStdString(), qos);
}

/* 接收到消息 */
void MQTTBase::do_received(const QMQTT::Message& message)
{
    // SPDLOG_LOGGER_INFO(m_logger,"MQTTBase接收到一条消息:{}", message.topic().toStdString());
    recvMessage(message);
}