#include "FrequencyTuning.h"
#include <iostream>
#include <QDateTime>

FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent)
{
    connect(&this->serialUtil, &QSerialPortUtil::dataRecieved,
            this, &FrequencyTuning::dataReceivedHandler);

    kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS);
    kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC);
    kafkaUtil.createProducer();

    this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name());
}

FrequencyTuning::~FrequencyTuning()
{
    disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved,
               this, &FrequencyTuning::dataReceivedHandler);
}



void FrequencyTuning::dataReceivedHandler(QByteArray data)
{
    this->dataBuff.append(data);

    std::cout << dataBuff.toStdString() << std::endl;

    QList<QByteArray> frameList = protocol->extractFrameList(this->dataBuff);

    if (frameList.size() > 0)
    {
        for (int i = 0; i < frameList.size(); i++)
        {
            QByteArray frameByte = frameList.at(i);

            int frameType = protocol->checkFrame(frameByte);
            DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType);
            if (ftFrameDto != nullptr)
            {
                // ★解析成数据对象
                bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType);

                // 解析成功
                if (parse == true)
                {
                    QDateTime now = QDateTime::currentDateTime();
                    ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz");
                    ftFrameDto->milisecond = now.toMSecsSinceEpoch();
                    ftFrameDto->rawFrame = frameByte;

                    ftFrameDto->devCode = devCode;

                    this->afterFramePhase(ftFrameDto);
                }

                // 在此处释放内存，不影响后续显示
                // 不在此处释放内存则会导致内存持续增加
                // 具体原因不明
                delete ftFrameDto;
            }
        }
    }
}

void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto)
{
    std::cout << "frame type: " << typeid(* frameDto).name() << std::endl;
    std::cout << frameDto->rawFrame.toStdString() << std::endl;

    // 0. 输出到日志文件中
    QString date = frameDto->timestamp.mid(0, 10);

    // 1. 原始字节数组数据
    QString filename = "raw_" + devCode + ".log";
    QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size());
    QLogUtil::writeRawDataLogByDate(date, filename, content);

    // 2. 解析后的json数据
    QString frameFilename = "frame_" + devCode + ".log";
    QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact);
    QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent);

    // 3. 输出到中间件，执行后续处理过程
    if (SettingConfig::getInstance().NEED_KAFKA == 1)
    {
        QJsonObject jsonObj = frameDto->toJSON();
        jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID);
        jsonObj.insert("deviceId", deviceId);
        kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact)));
    }

    // 4. 在界面上简单显示相差数据结果
    emit this->sendDataToDraw(frameDto);
}

void FrequencyTuning::sendDataToSerial(QByteArray data)
{
    data.append(FRAME_TAIL);
    this->serialUtil.sendData(data);

    // 记录日志
    // 0. 输出到日志文件中
    QDateTime now = QDateTime::currentDateTime();
    QString date = now.toString("yyyy-MM-dd");

    // 1. 原始字节数组数据
    QString filename = "raw_" + getDevCode() + ".log";
    QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size());
    QLogUtil::writeRawDataLogByDate(date, filename, content);
}
