//
// Created by dtx on 2022/3/22.
//

#include "SquashfsTask.h"
#include "Process.h"
#include "Device.h"
#include "FsTab.h"
#include "Utils.h"

#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDateTime>
#include <QDebug>

SquashfsTask::SquashfsTask() : AsyncTask()
{
    m_readResult = new QTimer;
    connect(m_readResult, &QTimer::timeout, this, &SquashfsTask::readResultSlot);
}

SquashfsTask::~SquashfsTask()
{
    if (nullptr != m_readResult) {
        if (m_readResult->isActive()) {
            disconnect(m_readResult, &QTimer::timeout, this, &SquashfsTask::readResultSlot);
            m_readResult->stop();
        }
        delete m_readResult;
        m_readResult = nullptr;
    }
}

bool SquashfsTask::makeSquashfs(const QString &srcDir, const QString &destFile)
{
    QDir dirExist;
    // 检查源目录是否存在
    if (!dirExist.exists(srcDir)) {
        qInfo()<<"SquashfsTask makeSquashfs, not exists";
        return false;
    }

    // 检查目标目录是否存在
    dirExist.mkpath(destFile.left(destFile.lastIndexOf("/")));
    if (!dirExist.exists(destFile.left(destFile.lastIndexOf("/")))) {
        qInfo()<<"SquashfsTask makeSquashfs, not exists destFile";
        return false;
    }

    if (m_timeStr.isEmpty()) {
        m_startTime = QTime::currentTime();
    } else {
        m_startTime = QTime::fromString(m_timeStr);
    }

    m_currentProgressValue = 1;

    int cpuCores = Utils::getCPUCores();
    if (cpuCores > 1) {
        cpuCores--;
    }

    // 制作 squashfs 文件 命令为： mksquashfs srcDir destFile
    m_cmd = "mksquashfs";
    m_args.append(srcDir);
    m_args.append(destFile);
    m_args.append("-processors");
    m_args.append(QString("%1").arg(cpuCores));
    m_args.append("-no-sparse");
    // m_args.append("-mem");
    // m_args.append("512M");
    m_readResult->start(1000);
    start();

    return true;
}

bool SquashfsTask::extractSquashfs(const QString &srcFile, const QString &destDir)
{
    // 检查源目录是否存在
    if (!QFile::exists(srcFile)) {
        qInfo()<<"SquashfsTask extractSquashfs, not exists srcFile = "<<srcFile;
        return false;
    }

    // 检查目标目录是否存在
    QDir dirExist;
    dirExist.mkpath(destDir.left(destDir.lastIndexOf("/")));
    if (!dirExist.exists(destDir.left(destDir.lastIndexOf("/")))) {
        qInfo()<<"SquashfsTask extractSquashfs, not exists destDir = "<<destDir;
        return false;
    }

    if (m_timeStr.isEmpty()) {
        m_startTime = QTime::currentTime();
    } else {
        m_startTime = QTime::fromString(m_timeStr);
    }

    m_currentProgressValue = 1;

    int cpuCores = Utils::getCPUCores();
    if (cpuCores > 1) {
        cpuCores--;
    }

    // 解压 squashfs 文件 命令为： unsquashfs srcFile
    m_cmd = "unsquashfs";
    m_args.append("-p");
    m_args.append(QString("%1").arg(cpuCores));
    m_args.append("-d");
    m_args.append(destDir);
    m_args.append(srcFile);
    m_readResult->start(1000);
    start();

    return true;
}


bool SquashfsTask::buildArgumentsForBackup()
{
    return true;
}

bool SquashfsTask::buildArgumentsForRestore(const QString &fromDir)
{
    return true;
}

void SquashfsTask::doResult()
{
    m_readResult->stop();
    m_currentProgressValue = 100;

    QJsonObject jsonObject;
    jsonObject["progress"] = m_currentProgressValue;
    int errCode = m_process->exitCode();
    if (m_process->exitStatus() != QProcess::NormalExit || errCode != 0) {
        QString err = m_process->readAllStandardError();
        qInfo()<<"SquashfsTask readAllStandardError, err = "<<err;
        jsonObject.insert("errMsg", err);
        Q_EMIT error(jsonObject);
    } else {
        Q_EMIT progressChanged(jsonObject);
        Q_EMIT success(jsonObject);
    }

    Q_EMIT taskFinished();
    return;
}

void SquashfsTask::readResultSlot()
{
    if (m_process != nullptr) {
        QDir dir(m_checkPath);
        if (!dir.exists()) {
            QString errLogs = QString("src path not exit: %1").arg(m_checkPath);
            qCritical() << errLogs;
            this->kill();
            return ;
        }

        QString line = m_process->readAll();
        int processPos = line.indexOf("]");
        if (processPos != -1) {
            line.replace("\t", "");
            line.replace("\n", "");
            line = line.right(line.length() - processPos);
            line = line.right(line.length() - line.lastIndexOf(" "));
            QString processValue = line.left(line.indexOf("\%"));
            m_currentProgressValue = processValue.toInt();
        }
        QJsonObject valueObj;
        valueObj["progress"] = m_currentProgressValue;
        Q_EMIT progressChanged(valueObj);
    }
}

void SquashfsTask::readStandardOutput()
{
    AsyncTask::readStandardOutput();
}

void SquashfsTask::readAllStandardError()
{
    AsyncTask::readAllStandardError();
}

void SquashfsTask::setCheckPath(const QString &path)
{
    m_checkPath = path;
}