#pragma once
#include <QString>
#include <QObject>
#include <QLibrary>
#include <QDateTime>
#include "Thread/threadcontroller.h"

#define LH_HTTPAPI_SUCC 0

const int LHHTTPAPI_BUFFER_SIZE = 1024*1024;
// 用New
#define LHAPI_BUFFER_SIZE_NEW 2048000
#define LHAPI_BUFFER_SIZE_ARY 4096

// token 超时
#define  TOKENTIME 20*60
extern int g_nHttpTimeOut;

// 操作类型【1查询 2更新 3删除 4插入 5存储过程】
enum enDBOperatorType
{
    EDBOT_Select = 1,
    EDBOT_Update,
    EDBOT_Delete,
    EDBOT_Insert,
    EDBOT_Procedure,
};


class lhhttpapi : public QObject
{
    Q_OBJECT
public:
    typedef void* (*FunDBInit)(const char* lpUrl,bool bismulti);
    typedef int (*FunDBLogin)(const char *plocalip,const char *pSerid, const char* CType, char *pszUserToken, int nSize,bool bismulti, void* phttpip);
    typedef int (*FunDBGetServerList)(char *pszList, int nSize,bool bismulti, void* phttpip);
    typedef int (*FunDBGetChannelList)(const char* pSerid,char *pszList, int nSize,bool bismulti, void* phttpip);
    typedef int (*FunDBDoInterface)(const char* pSerid,const char* CType,const char* strtoken,int nOperatorType, const char * strParamXml, char *strRetXml, int nSize,bool bismulti, void* phttpip);
    typedef int64_t (*FunDoGetHttpFileSize)(const char* pHttAddr);
    typedef int64_t (*FunDoGetHttpFileContent)(const char* lpHttpAddr, char *pszContent, int nSize);
    typedef int (*FunDoUploadFtpFile)(const char* pszLocalFilePath, const char* pszFtpFilePath);
    typedef int (*FunDoUploadFtpFileContent)(const char * szFileContent, int nSize, const char* strFtpFilePath);

    typedef int (*FunDoCurlDeleteFtpFile)(const char* user, const char* pwd, const char* pszFtpFile);
    typedef int (*FunDoCurlUploadFtpFile)(const char* user, const char* pwd, const char* pszLocalFilePath, const char* pszFtpFile);
    typedef int (*FunDoCurlUploadFtpFileContent)(const char* user, const char* pwd, const char* pszFileContent, int nSize, const char* pszFtpFile);

//    typedef int (*FunUnInit)();
    typedef int (*FunDoGetLastError)(char *pError, int nLen, int *nErrorCode);
    typedef int (*FunDoRelease)(bool bismulti, void* phttpip);
public:
    explicit lhhttpapi(QObject *parent = nullptr);
    ~lhhttpapi();
public:
    QLibrary *m_pQLib;

    FunDoRelease fnDoRelease;
    FunDBInit fnDBInit;
    FunDBLogin fnDBLogin;
    FunDBGetServerList fnDBGettServerList;
    FunDBGetChannelList fnDBGetChannelList;
    FunDBDoInterface fnDBDoInterface;
    FunDoGetHttpFileSize fnDoGetHttpFileSize;
    FunDoGetHttpFileContent fnDoGetHttpFileContent;
    FunDoUploadFtpFile fnDoUploadFtpFile;
    FunDoUploadFtpFileContent fnDoUploadFtpFileContent;
    FunDoCurlDeleteFtpFile fnDoCurlDeleteFtpFile;
    FunDoCurlUploadFtpFile fnDoCurlUploadFtpFile;
    FunDoCurlUploadFtpFileContent fnDoCurlUploadFtpFileContent;
//    FunUnInit fnUnInit;
    FunDoGetLastError fnGetLastError;

    QMutex m_mutexWorkerDestroy;
    QWaitCondition m_Condition;
public:
    bool Load(QString file);
    bool UnLoad();
    int  DoRelease(bool bismulti = false, void* phttpip=nullptr);
    int DBLogin(const QString& pLocalip,const QString &pSerid,const QString &appType, QString &pszUserToken,bool bismulti = false, void* phttpip=nullptr);
    int DoGetToken(QString &szToken,bool bismulti = false, void* phttpip=nullptr);

//    void DoGetTokenAgain();

    int DBGetServerList(char *pszList, int nSize,bool bismulti = false, void* phttpip=nullptr);
    int DBGetChannelList(const char* pSerid,char *pszList, int nSize,bool bismulti = false, void* phttpip=nullptr);
    int DBDoInterface(int nOperatorType, const QString &strParamXml, QString &strRetXml, bool wait = false,bool bismulti = false, void* phttpip=nullptr);
    void* DBInit (const char *lpUrl,bool bismulti = false);
    int DoGetLastError(char *pError, int nLen, int *nErrorCode);

    QString DoGetLastError(int *nErrorCode);
    int64_t DoGetHttpFileSize(const QString &url);
    int64_t DoGetHttpFileContent(const QString &url, char *pszContent, int nSize);
   // int64_t DoGetHttpPNGFile(const QString &url, QPixmap &outPixmap);
    bool DoUploadFtpFile(const QString &localFilePath, const QString &ftpFilePath);
    bool DoUploadFtpFileContent(const char * szFileContent, int nSize, const QString &ftpFilePath);
    bool DoCurlDeleteFtpFile(const QString &targetFilePath);
    bool DoCurlDeleteFtpFile(const QString &user, const QString &pwd, const QString &targetFilePath);
    bool DoCurlUploadFtpFile(const QString &localFilePath, const QString &destFilePath);
    bool DoCurlUploadFtpFile(const QString &user, const QString &pwd, const QString &localFilePath, const QString &destFilePath);
    bool DoCurlUploadFtpFileContent(const char * szFileContent, int nSize, const QString &destFilePath);
    bool DoCurlUploadFtpFileContent(const QString &user, const QString &pwd, const char * szFileContent, int nSize, const QString &destFilePath);
private slots:

    void OnWorkerFinished();

private:
    QString m_Localip; // localip

    QString m_Serid; // 当前服务数据库id

    QString m_appType; // 设备类型

    QString m_strtoken;// token

    QDateTime m_lasttimer; // 最后一个获取token的时间
};

class DoInterfaceObject : public ThreadWorker
{
    Q_OBJECT
public:
    explicit DoInterfaceObject(lhhttpapi *pApi, const QString &strToken, int nOperatorType, const QString &strParamXml,bool bismulti = false,void* phttpip=nullptr);
    virtual ~DoInterfaceObject() override {}
    QString GetRetXML() const {return m_strRetXml;}
    int GetResult() const {return m_nResult;}
public slots:
    virtual void DoInit() override {}
    virtual void DoWork() override;
signals:
    void sig_WorkFinished();
public:
    lhhttpapi *m_pApi;
    QString m_strToken;
    int m_nOperatorType;
    QString m_strParamXml;
    QString m_strRetXml;
    int m_nResult;
    bool m_bismulti;
    void* m_phttpip;
};