#ifndef MEASUREMENTDATAMANAGER_H
#define MEASUREMENTDATAMANAGER_H

#include "measurementDataUtils.h"
#include <QObject>
#include <QHash>
#include <QUrl>

class QSettings;
class QNetworkAccessManager;
class QNetworkReply;
class WebSocketClient;

class MeasurementDataManager : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY(MeasurementDataManager) //禁止拷贝，等价于：DataManager(const DataManager&) = delete; DataManager& operator=(const DataManager&) = delete;

public:
    static MeasurementDataManager* instance();
    static void destroyInstance();

    void requestData(const QStringList& measurements, QObject* requester);
    void cancelRequest(const QStringList& measurements, QObject* requester);
    MeasurementDataPoint getLastestRealtimeData(const QString& dataID);
    void queryHistoricalEvents(const QString& dataID, const QDateTime& startTime, const QDateTime& endTime, const QString& step, const QString& type = "phasor");

private slots:
    void onReceiveRealtimeData(const QString& dataMsg);
    void onHistoricalRequestFinished(const QString& dataID, QNetworkReply* reply);
    void cleanUpDataCache();

private:
    struct RealtimeConfig
    {
        QString host;
        int port;
        QString httpPath;
        QString websocketPath;
        int timeout; //请求超时(毫秒)
        int maxRetries; //最大重试次数
        int retryInterval; //重试间隔

        RealtimeConfig()
            : timeout(3000)
            , maxRetries(3)
            , retryInterval(1000)
        {}
    };

    struct HistoricalConfig
    {
        QUrl baseUrl;
        int timeout; //请求超时(毫秒)
        int maxRetries; //最大重试次数
        int retryInterval; //重试间隔

        HistoricalConfig()
            : timeout(3000)
            , maxRetries(3)
            , retryInterval(1000)
        {}
    };

    struct ServiceConfig
    {
        RealtimeConfig realtimeCfg;
        HistoricalConfig historicalCfg;
    };

    explicit MeasurementDataManager();
    ~MeasurementDataManager();

    static MeasurementDataManager* m_instance;

    class CGarbo
    {
    public:
        CGarbo() {};
        ~CGarbo()
        {
            if(m_instance)
                delete m_instance;
            m_instance = nullptr;
        }
    };

    void initialize();
    //实时数据
    void buildSubscriptionRequest(const QString& action, const QStringList& measurements);
    void startSubscription(const QStringList& measurements);
    void stopSubscription();
    void addSubscriptionData(const QStringList& measurements);
    void removeSubscriptionData(const QStringList& measurements);
    void processSubscriptionResponse(const QString& action, QNetworkReply* reply);
    void getSubscriptionRealtimeData();
    //历史数据
    QUrl buildHistoricalQueryUrl(const QString& dataID,const QDateTime& startTime, const QDateTime& endTime, const QString& step, const QString& type);
    void processHistoricalResponse(const QString& dataID, const QByteArray& data);

    //配置相关
    ServiceConfig m_serviceConfig;
    QSettings* m_settings;
    QString m_settingsFile;
    bool m_isVaildSettingsFile;

    //服务相关
    QString m_clientID;
    QNetworkAccessManager* m_networkManager;
    WebSocketClient* m_webSocketClient;

    //数据缓存
    QHash<QString, QSharedPointer<MeasurementData>> m_dataCache;
    QTimer m_dataCleanupTimer;
    int m_dataCleanupInterval;

    //请求记录
    QHash<QString, QSet<QObject*>> m_dataRequesetRecord;
};

#endif
