#pragma once
#include <QString>
#include <QObject>
#include <QLibrary>
#include <QDateTime>
#include <QMutex>
#include <QWaitCondition>
// #include "Common/singleton.h"
#include "threadcontroller.h"

#define LH_HTTPAPI_SUCC 0

// 用New
#define LHAPI_BUFFER_SIZE_NEW 2048000
#define LHAPI_BUFFER_SIZE_ARY 4096

extern int g_nHttpTimeOut;

// 操作类型【1查询 2更新 3删除 4插入 5存储过程】
enum enDBOperatorType
{
    EDBOT_Select = 1,
    EDBOT_Update,
    EDBOT_Delete,
    EDBOT_Insert,
    EDBOT_Procedure,
    EDBOT_Batch,    // 单动作批量操作,失败全部回滚
    EDBOT_BatchTransAction // 多动作批量操作,失败回滚
};

class lhhttpapi : public QObject
{
    Q_OBJECT
public:
    typedef int (*FunDBInit)(const char* lpUrl);
    typedef int (*FunDBLogin)(const char *pLocalIP, const char *pSerid, const char* CType, char *pszUserToken, int nSize);
    typedef int (*FunDBGetServerList)(char *pszList, int nSize);
    typedef int (*FunDBGetServerInfo)(const char* pSerid, const char* pszUserToken, char* pServerInfo, int nSize);
    typedef int (*FunDBGetChannelList)(const char* pSerid,char *pszList, int nSize);
    typedef int (*FunDBDoInterface)(const char* pSerid,const char* CType,const char* strtoken,int nOperatorType, const char * strParam, char *strRet, int nSize);
    typedef int (*FunDoGetLastError)(char *pError, int nLen, int *nErrorCode);

    typedef int (*FunSetHttpTimeOut)(int nTimeout);

    // 获取网络文件大小,返回文件大小
    typedef int64_t (*FunDoGetHttpFileSize)(const char *pszHttpAddr);

    // 获取网络文件内容,返回内容大小
    typedef int64_t (*FunDoGetHttpFileContent)(const char* pHttpAddr, char *pszContent, int nSize);

    // 获取汉字拼音首字母,空格、数字等其它字符保持不动
    typedef int (*FunDoWord2Pyjc)(const char* pszWord, char *pszContent, int nSize);

    // 文件上传FTP
    typedef int (*FunDoUploadFtpFile)(const char* pszLocalFilePath, const char* pszFtpFilePath);
    typedef int (*FunDoUploadFtpFileContent)(const char* pszFileContent, int size, const char* pszFtpFilePath);

    // FTP
    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 (*FunDoGetDBInfo)(const char* strSerid, const char* strtoken, char* pDBInfo, int nsize);
public:
    explicit lhhttpapi(QObject *parent = nullptr);
    ~lhhttpapi();

public:
    QLibrary *m_pQLib;

    FunDBInit fnDBInit;
    FunDBLogin fnDBLogin;
    FunDBGetServerList fnDBGettServerList;
    FunDBGetChannelList fnDBGetChannelList;
    FunDBGetServerInfo fnDBGetServerInfo;

    FunSetHttpTimeOut fnSetHttpTimeOut;
    FunDoGetHttpFileSize fnGetHttpFileSize;
    FunDoGetHttpFileContent fnGetHttpFileContent;
    FunDoGetLastError fnGetLastError;
    FunDoWord2Pyjc    fnDoWord2Pyjc;
    FunDoUploadFtpFile fnDoUploadFtpFile;
    FunDoUploadFtpFileContent fnDoUploadFtpFileContent;

    FunDoCurlDeleteFtpFile  fnDoCurlDeleteFtpFile;
    FunDoCurlUploadFtpFile  fnDoCurlUploadFtpFile;
    FunDoCurlUploadFtpFileContent fnDoCurlUploadFtpFileContent;

    FunDoGetDBInfo  fnDoGetDBInfo;

    QMutex m_mutexWorkerDestroy;
    QWaitCondition m_Condition;
    FunDBDoInterface fnDBDoInterface;

public:
    bool Load(QString file);
    bool UnLoad();

    int SetHttpTimeOut(int nTimeout);
    QString DoGetLastError(int *nErrorCode);
    QString GetServerID() const {return m_serID;}
    QString GetClientType() const {return m_clientType;}

    int DBQInit(QString strUrl);
    int DBQGetServerList(QString& serverList);
    int DBQGetServerInfo(const QString& serid, QString& serverInfo);
    /**
     * @brief 登录数据库
     * 
     * @param LocalIP 
     * @param Serid 
     * @param CType 
     * @param strUserToken 传出参数
     * @return int 
     */
    int DBQLogin(QString LocalIP, QString Serid, QString CType, QString &strUserToken);
    int DBQDoInterface(int nOperatorType, const QString &strParamXml, QString &strRetXml, bool wait = true);

private slots:
    void OnWorkerFinished();
private:
    QString m_token;
    QMutex m_mtx;
    QString m_serID;
    QString m_clientType;
    QTimer* m_tUpToken;
};

class DoInterfaceObject : public ThreadWorker
{
    Q_OBJECT
public:
    explicit DoInterfaceObject(lhhttpapi *pApi, const QString &strToken, int nOperatorType, const QString &strParamXml);
    virtual ~DoInterfaceObject() override {}
    QString GetRetXML() const {return m_strRetXml;}
    int GetResult() const {return m_nResult;}
public slots:
    void DoInit() override {}
    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;
};