#ifndef QTFTP_H
#define QTFTP_H

#include <QObject>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QFile>
#include <QTimer>




/**
 * @brief 封装一个FTP类,这里没有单开一个线程,在调用线程中工作
 *        这里的上传下载路径都是相对路径,不包含前面的IP地址和端口
 *   注意:目前只支持单个请求,即一个请求完成后才能进行下一个请求
 */
class QtFtp : public QObject
{
    Q_OBJECT
public:
    explicit QtFtp(QObject* parent = nullptr);
    ~QtFtp();

    /* 设置目标主机IP和端口 */
    void setHostAndPort(const QString& host,int port = 21);
    /* 设置目标设备的用户名和密码 */    
    void setUserPasswd(const QString& user,const QString& pw);
    /* 上传文件 */   
    void putFile(const QString& fileName,const QString& farPath);
    /* 上传文件,直接上传内存数据 */   
    void putFile(const QByteArray& data,const QString& farPath);
    /* 下载文件 */
    void getFile(const QString& fileName,const QString &srcPath);   
    /* 下载文件,直接下载到内存,路径是相对路径,不包含前面的IP地址和端口 */
    void getFile(QByteArray& data,const QString& srcPath);
    /* 等待完成 */
    bool waitFinished(int msecs = 30000);
    /* 获取结果 */
    bool getResult();                                               

    /* 创建目录 */
    bool createDir(const QString& path);

signals:
    /* 文件上传成功或失败 */
    void signal_uploadState(bool flag);
    /* 文件下载成功或失败 */
    void signal_downloadState(bool flag);
    /* 上传进度 */                           
    void signal_uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    /* 下载进度 */      
    void signal_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);

#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    /* 将QNetworkReply的一些信号转换成自定义的信号 */
    void signal_error(QNetworkReply::NetworkError);
#endif

private slots:
    /* 上传完成 */
    void do_uploadFinished();
    /* 下载完成,保存文件 */
    void do_downloadFinished();
    /* 下载完成,保存数据 */
    void do_downloadFinishedToData();
    /* 上传进度 */
    void do_uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    /* 下载进度 */
    void do_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
    /* ftp其他任务完成槽函数 */
    void do_finished();
    /* 定时器超时函数 */
    void do_timeout();

    #if defined (QT_VERSION) && QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    void do_ftpReplyError(QNetworkReply::NetworkError error);       /* ftp发送错误槽函数 */
    #endif
private:
    bool m_isFinished = false;                                      /* 上传或下载是否完成 */
    bool m_result = false;                                          /* 上传或下载是否成功 */
    QTimer m_timer;                                                 /* 定时器,用于等待上传或下载完成 */
    QUrl m_url;
    QFile m_file;                                                   /* 存储下载的文件 */
    QFile m_fileUpload;                                             /* 存储上传的文件 */
    QByteArray *m_downloadData = nullptr;                           /* 存储下载的数据 */
    QNetworkAccessManager m_manager;
    QNetworkReply* m_reply = nullptr;
};



#endif /* QTFTP_H */