#include <QRegExp>
#include <globaldefine.h>
#include <QDir>
#include <QDateTime>
#include <QCoreApplication>
#include <QMessageBox>
#include <QMetaEnum>

bool gVideoCompress = true;
bool gVideoTranscoding = true;
bool gTextAntialiasing = false;
bool gShowLoraScreen = false;
bool gWidthSplit = false;

QNetworkRequest netReq(const QString &url, int timeout, const QVariant &contentType) {
    QNetworkRequest request{url};
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
    request.setTransferTimeout(timeout);
    if(contentType.isValid()) request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
    return request;
}
QString parseReplyJson(QNetworkReply *reply, QJsonDocument *outJson) {
    reply->deleteLater();
    auto error = reply->error();
    if(error != QNetworkReply::NoError) {
        auto errStr = reply->errorString();
        if(error!=QNetworkReply::InternalServerError || ! errStr.endsWith("replied: Unknown")) {
            if(error==QNetworkReply::OperationCanceledError) {
                error = QNetworkReply::TimeoutError;
                errStr = QCoreApplication::translate("Def","Connection Timeout");
            }
            return QString(QMetaEnum::fromType<QNetworkReply::NetworkError>().valueToKey(error))+" ("+QString::number(error)+") "+errStr+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+reply->readAll();
        }
    }
    auto status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(status != 200) return QString::number(status)+" "+reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+reply->readAll();
    if(outJson) {
        auto data = reply->readAll();
        QJsonParseError jsonErr;
        *outJson = QJsonDocument::fromJson(data, &jsonErr);
        if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+data;
    }
    return "";
}
QString checkReplyForJson(QNetworkReply *reply, QJsonDocument *doc, QByteArray *outData) {
    reply->deleteLater();
    auto error = reply->error();
    auto data = reply->readAll();
    if(outData) *outData = data;
    if(error != QNetworkReply::NoError) {
        auto errStr = reply->errorString();
        if(error!=QNetworkReply::InternalServerError || ! errStr.endsWith("replied: Unknown")) {
            if(error==QNetworkReply::OperationCanceledError) {
                error = QNetworkReply::TimeoutError;
                errStr = QCoreApplication::translate("Def","Connection Timeout");
            }
            return QString(QMetaEnum::fromType<QNetworkReply::NetworkError>().valueToKey(error))+" ("+QString::number(error)+") "+errStr+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+data;
        }
    }
    auto status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(status != 200) return QString::number(status)+" - "+reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+data;
    QJsonParseError jsonErr;
    QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr);
    if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+":\n"+data;
    if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+":\n"+data;
    if(doc) doc->swap(json);
    return "";
}

bool isTextValid(const QString &strIP){
    if(! strIP.isEmpty()) {
        QRegExp rx2("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
        if (!rx2.exactMatch(strIP)) return false;
    }
    return true;
}
QString getRandomString(int len) {
    static const char table[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static const int tableSize = sizeof(table) - 1;
    QString str;
    str.resize(len);
    for(int i=0; i<len; i++) str[i] = table[rand() % tableSize];
    return str;
}
bool isFileExist(QString fullFileName)
{
    QFileInfo fileInfo(fullFileName);
    if(fileInfo.isFile())
    {
        return true;
    }
    return false;
}

quint64 dirFileSize(const QString &path)
{
    QDir dir(path);
    quint64 size = 0;
    //dir.entryInfoList(QDir::Files)返回文件信息
    foreach(QFileInfo fileInfo, dir.entryInfoList(QDir::Files))
    {
        //计算文件大小
        size += fileInfo.size();
    }
    //dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)返回所有子目录，并进行过滤
    foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
    {
        //若存在子目录，则递归调用dirFileSize()函数
        size += dirFileSize(path + QDir::separator() + subDir);
    }
    return size;
}

void HttpPostByTypeJsonObject(HpptClient *pHpptClient, QString strUrl, QJsonObject json) {
    pHpptClient->httpPost(strUrl, QJsonDocument(json).toJson(QJsonDocument::Compact));
}
bool copyDir(const QString &source, const QString &destination, bool override)
{
    QDir directory(source);
    if (!directory.exists())
    {
        return false;
    }


    QString srcPath = QDir::toNativeSeparators(source);
    if (!srcPath.endsWith(QDir::separator()))
        srcPath += QDir::separator();
    QString dstPath = QDir::toNativeSeparators(destination);
    if (!dstPath.endsWith(QDir::separator()))
        dstPath += QDir::separator();


    bool error = false;
    QStringList fileNames = directory.entryList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
    for (QStringList::size_type i=0; i != fileNames.size(); ++i)
    {
        QString fileName = fileNames.at(i);
        QString srcFilePath = srcPath + fileName;
        QString dstFilePath = dstPath + fileName;
        QFileInfo fileInfo(srcFilePath);
        if (fileInfo.isFile() || fileInfo.isSymLink())
        {
            if (override)
            {
                QFile::setPermissions(dstFilePath, QFile::WriteOwner);
            }
            QFile::copy(srcFilePath, dstFilePath);
        }
        else if (fileInfo.isDir())
        {
            QDir dstDir(dstFilePath);
            dstDir.mkpath(dstFilePath);
            if (!copyDir(srcFilePath, dstFilePath, override))
            {
                error = true;
            }
        }
    }


    return !error;
}
unsigned char GetCheckCodeIn8(unsigned char * pBuffer,unsigned int uiSize) {
    unsigned int i=0;
    unsigned char ucCheckCode=0;
    for (i=0;i<uiSize;i++) ucCheckCode+=pBuffer[i];
    return (~ucCheckCode)&0x0ff;
}
