#ifndef DEVICEPROTOCOLBASE_H
#define DEVICEPROTOCOLBASE_H

#include <QObject>
#include "dto/DeviceFrameBaseDto.h"

static const QString FRAME_TAIL = "\r\n"; // 帧尾
static const QString FRAME_CONTENT_SEP = ","; // 帧内分隔符
static const QString FRAME_SUM_SEP = "*"; // 异或和字段的分隔符
static const int FRAME_SUM_LENGTH = 2;
static const int FRAME_SUB_MIN_SIZE = 2;

static const QString SIGNAL_GENERATOR_INTERFACE_FRAME_HEAD = "$GLC"; // 帧头
static const QString SIGNAL_GENERATOR_STATUS_FRAME_HEAD = "$GLF"; // 帧头
static const QString SIGNAL_GENERATOR_MJD_FRAME_HEAD = "$GPMJD"; // 帧头
static const QString SIGNAL_GENERATOR_ZDA_FRAME_HEAD = "$GPZDA"; // 帧头

static const QString TIME_SWITCHER_INTERFACE_FRAME_HEAD = "$GLC"; // 帧头
static const QString TIME_SWITCHER_STATUS_FRAME_HEAD = "$GLF"; // 帧头

static const QString FREQ_SWITCHER_INTERFACE_FRAME_HEAD = "$GLC"; // 帧头
static const QString FREQ_SWITCHER_STATUS_FRAME_HEAD = "$GLF"; // 帧头

static const QString FREQ_REPLICATOR_STAUTS_FRAME_HEAD = "AA55";

static const QString TIME_REPLICATOR_STATUS_FRAME_HEAD = "$";
static const QString TIME_REPLICATOR_STATUS_FRAME_TAIL = "*";

static const QString FREQ_TUNN_STATUS_FRAME_HEAD = "$";
static const QString FREQ_TUNN_STATUS_FRAME_TAIL = "*";


static const int FREQUENCY_TUNING_FREQ_FRAME_SUB_COUNT = 26;
static const int FREQUENCY_TUNING_PULSE_FRAME_SUB_COUNT = 5;

static const int SIGNAL_GENERATOR_INTERFACE_FRAME_SUB_COUNT = 2;
static const int SIGNAL_GENERATOR_STATUS_FRAME_SUB_COUNT = 11;
static const int SIGNAL_GENERATOR_ZDA_FRAME_SUB_COUNT = 6;
static const int SIGNAL_GENERATOR_MJD_FRAME_SUB_COUNT = 4;

static const int TIME_SWITCHER_INTERFACE_FRAME_SUB_COUNT = 1;
static const int TIME_SWITCHER_STATUS_FRAME_SUB_COUNT = 24;

static const int FREQ_SWITCHER_INTERFACE_FRAME_SUB_COUNT = 1;
static const int FREQ_SWITCHER_STATUS_FRAME_SUB_COUNT = 21;


static const int SIGNAL_GENERATOR_INTERFACE_FRAME_MIN_LENGTH = SIGNAL_GENERATOR_INTERFACE_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        SIGNAL_GENERATOR_INTERFACE_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;
static const int SIGNAL_GENERATOR_STATUS_FRAME_MIN_LENGTH = SIGNAL_GENERATOR_STATUS_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        SIGNAL_GENERATOR_STATUS_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;
static const int SIGNAL_GENERATOR_ZDA_FRAME_MIN_LENGTH = SIGNAL_GENERATOR_ZDA_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        SIGNAL_GENERATOR_ZDA_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;
static const int SIGNAL_GENERATOR_MJD_FRAME_MIN_LENGTH = SIGNAL_GENERATOR_MJD_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        SIGNAL_GENERATOR_MJD_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;

static const int TIME_SWITCHER_INTERFACE_FRAME_MIN_LENGTH = TIME_SWITCHER_INTERFACE_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        TIME_SWITCHER_INTERFACE_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;
static const int TIME_SWITCHER_STATUS_FRAME_MIN_LENGTH = TIME_SWITCHER_STATUS_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        TIME_SWITCHER_STATUS_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;

static const int FREQ_SWITCHER_INTERFACE_FRAME_MIN_LENGTH = FREQ_SWITCHER_INTERFACE_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        FREQ_SWITCHER_INTERFACE_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;
static const int FREQ_SWITCHER_STATUS_FRAME_MIN_LENGTH = FREQ_SWITCHER_STATUS_FRAME_HEAD.length() +
        FRAME_TAIL.length() + 1 + FRAME_SUB_MIN_SIZE +
        FREQ_SWITCHER_STATUS_FRAME_SUB_COUNT * FRAME_SUB_MIN_SIZE;


static const QString FREQUENCY_TUNING_FREQ_FRAME_TYPE = "0301";
static const QString FREQUENCY_TUNING_LOCK_FRAME_TYPE = "0302";

static const QString SIGNAL_GENERATOR_INTERFACE_FRAME_TYPE = "0401";
static const QString SIGNAL_GENERATOR_STATUS_FRAME_TYPE = "0402";
static const QString SIGNAL_GENERATOR_MJD_FRAME_TYPE = "0403";
static const QString SIGNAL_GENERATOR_ZDA_FRAME_TYPE = "0404";

static const QString TIME_SWITCHER_STATUS_FRAME_TYPE = "0501";
static const QString TIME_SWITCHER_INTERFACE_FRAME_TYPE = "0502";

static const QString FREQ_SWITCHER_STATUS_FRAME_TYPE = "0601";
static const QString FREQ_SWITCHER_INTERFACE_FRAME_TYPE = "0602";

static const QString B_CODE_TERMINAL_STATUS_FRAME_TYPE = "0701";

static const QString TIME_REPLICATOR_STATUS_FRAME_TYPE = "0901";
static const QString TIME_REPLICATOR_PHASE_CMDREP_TYPE = "0911";
static const QString TIME_REPLICATOR_DELAY_CMDREP_TYPE = "0912";

static const QString FREQ_REPLICATOR_STATUS_AB_FRAME_TYPE = "1001";
static const QString FREQ_REPLICATOR_STATUS_CD_FRAME_TYPE = "1002";

static const QString NTP_SERVER_STATUS_FRAME_TYPE = "1101";
static const QString NTP_SERVER_CMDREP_TYPE = "1111";


class DeviceProtocolBase : public QObject
{
    Q_OBJECT
public:
    explicit DeviceProtocolBase(QObject *parent = nullptr);

    static DeviceProtocolBase * deviceProtocolFactory(QString deviceType);

    QString calculateXOR(QByteArray byteArray);
    QString buildCRC16(QByteArray byteArray);

    virtual DeviceFrameBaseDto * frameFactory(int frameType) = 0;
    virtual int checkFrame(QByteArray rawData) = 0;
    virtual QList<QByteArray> extractFrameList(QByteArray rawData) = 0;
    virtual bool parseDeviceFrameData(QByteArray rawData, DeviceFrameBaseDto * frameData, int frameType) = 0;
    virtual QByteArray generateSettingCommand(QString devCode, QString commandType, QString valueSet);

signals:

};

#endif // DEVICEPROTOCOLBASE_H
