#include "downloader.h"
#include <QCoreApplication>
#include <QDebug>
#include <QJsonDocument>
#include <QRegularExpression>

Downloader::Downloader(QObject *parent)
    : QObject{parent}
{
    m_pNetWorkAccessManager = new QNetworkAccessManager(this);
    dir.setPath(QCoreApplication::applicationDirPath());
}

void Downloader::setUrl(const QString &_url)
{
    m_pUrl = QUrl(_url);
}

void Downloader::startDownload(const QString &_url)
{
    if(m_bIsDownloading)
        return;
    m_bIsDownloading = true;
    if(!_url.isEmpty())
        m_pUrl.setUrl(_url);

    if(!dir.exists())
    {
        dir.mkpath(".");
    }
    /* Rename old downloads */
    QString _path = dir.path() + "/" + m_fileName;
    if(QFile::exists(_path))
    {
        QFile _file(_path);
        _file.rename(_path + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd"));
    }

    QFile::remove(dir.filePath(m_fileName));
    QFile::remove(dir.filePath(m_fileName + ".part"));

    QNetworkRequest request;
    request.setUrl(m_pUrl);
    m_pReply = m_pNetWorkAccessManager->get(request);

    connect(m_pReply, &QNetworkReply::downloadProgress, this, [&](qint64 received, qint64 total)
    {
        emit doProgress(received, total);
        if (total > 0)
        {
            if(file.fileName() != (dir.filePath(m_fileName + ".part")))
                file.setFileName(dir.filePath(m_fileName + ".part"));
            if(!file.isOpen())
            {
                file.open(QIODevice::WriteOnly | QIODevice::Append);
            }
            file.write(m_pReply->readAll());
        }
    });
    connect(m_pReply, &QNetworkReply::metaDataChanged, this, [&]()
    {
        QString  filename = "";
        QVariant variant = m_pReply->header( QNetworkRequest::ContentDispositionHeader );
        if ( variant.isValid() )
        {
            QString contentDisposition = QByteArray::fromPercentEncoding( variant.toByteArray() ).constData();
            QRegularExpression regExp( "(.*)filename=\"(?<filename>.*)\"" );
            QRegularExpressionMatch match = regExp.match( contentDisposition );
            if ( match.hasMatch() )
            {
                filename = match.captured( "filename" );
            }
            m_fileName = filename;
            auto localApplicationFilePath = QCoreApplication::applicationDirPath();
            file.setFileName(localApplicationFilePath + "/" + m_fileName);
        };
    });
//    connect(m_pReply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    connect(m_pReply, &QNetworkReply::finished, this, [&]()
    {
        if(file.isOpen())
            file.close();
        if(!file.exists())
        {
            emit doShowInfo("not exits");
        }
        if(file.isOpen())
        {
            emit doShowInfo("not close");
        }
        if(!file.rename(dir.path() + "/" + m_fileName))
        {
            emit doShowInfo("rename file failed");
        }
        file.setFileName(dir.filePath(m_fileName));
        m_bIsDownloading = false;
        emit doFinished();
    });
    connect(m_pReply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SIGNAL(onError(QNetworkReply::NetworkError)));
}

void Downloader::checkVersion()
{
    QNetworkRequest request(CHECK_URL);
    m_pNetWorkAccessManager->get(request);
}

const QFile &Downloader::getFile() const
{
    return file;
}

const QDir &Downloader::getDir() const
{
    return dir;
}

const QString &Downloader::fileName() const
{
    return m_fileName;
}

void Downloader::setFileName(const QString &newFileName)
{
    m_fileName = newFileName;
}
