#include "processburndata.h"
#include "src/frame/logger.h"
#include "src/po/translation.h"
#include "src/data/datacdrom.h"
#include "src/data/datadirectory.h"
#include "src/view/modaldialog.h"
#include "src/view/execdialog.h"
#include "src/frame/signals.h"
#include "src/model/diroptutils.h"
#include "src/process/processlsof.h"

#include <QFileInfo>
#include <QDir>
#include <QCoreApplication>
#include <QStandardPaths>
#include <fstream>
#include <QDebug>

ProcessBurnData::ProcessBurnData(void *root, void *cdrom, QObject *parent) :
    ProcessBasic(parent),
    m_oFlag(false),
    m_bVerficationData(false),
    m_bGreateThan2GB(false),
    m_iErrorInfoNum(0),
    m_oProgressBarTimer_DVD(new QTimer(this))
{
    m_bCreateISO = false;
    m_oCDROM = cdrom;
    cloneCDROM = ((DataCDROM *)cdrom)->clone();
    m_oRoot = root;
    m_root = (DataDirectory *)m_oRoot;
    m_odestination=m_root->destination();
    m_bGreateThan2GB = m_root->isGreateThan2GByNewAddSingleFile();
    m_ototal = m_root->total(); //新旧文件总数量
    m_oSize = m_root->size(); // 新旧文件总大小
    m_oNewSize = m_root->nSize()/1024.0/1024.0; // 单位：MB   //所有新文件容量
    m_oDeviceBlock = cloneCDROM->device();

    auditburner=new QGSettings("org.ukui.kylinburner");
    auditlogpath="/var/log/kylin-burner/os_audit.log";
    m_isSpecialMachine=auditburner->get("burneraudit-isrunning").toBool();
    m_bVerficationData = cloneCDROM->settingVerficationData();

    qDebug() << __LINE__ << __func__ << "Verfication Data :" << m_bVerficationData;
    qDebug() << __LINE__ << __func__ << "ClossSession :" <<cloneCDROM->settingCloseSession() ;
    if (m_bVerficationData) {
        //拼接路径
        m_oTempPath = cloneCDROM->settingTempPath();

        if (m_oTempPath.endsWith("/")) {
            m_oTempPath = m_oTempPath + cloneCDROM->settingVolumnID();
        } else{
            m_oTempPath = m_oTempPath + '/' + cloneCDROM->settingVolumnID();
        }
    }

    m_fSpeed = 0;
    connect(m_oProgressBarTimer_DVD, SIGNAL(timeout()), this, SLOT(slotsProcessBarDVD()));
    connect(g_user_signal, &GlobalUserSignal::removeDisc, this, &ProcessBurnData::slotsRemoveDisc);

    if (cloneCDROM->mediumStatus() == DataMedium::MEDIUM_EMPTY)
    {
        LOGGER->registerName(this, _("PROCESS_BD"));
        title(_("Burning Data"));
        m_oProcessName = _("Burn Data");
        m_bAppendBurn = false;
    }
    else
    {
        LOGGER->registerName(this, _("PROCESS_AB"));
        title(_("Append Burning"));
        m_oProcessName = _("Append Burn");
        m_bAppendBurn = true;
    }
    setRange(0, 100);
    setValue(0);
    g_user_signal->setDeviceBusyStatus(m_oDeviceBlock,true);
}

ProcessBurnData::~ProcessBurnData()
{
    if(m_oProgressBarTimer_DVD!=nullptr)
        delete m_oProgressBarTimer_DVD;
    m_oProgressBarTimer_DVD = nullptr;

    if(cloneCDROM) {
        delete cloneCDROM;
    }
    cloneCDROM = nullptr;
    LOGGER->info("( ProcessBurnData::~ProcessBurnData)");
}

bool ProcessBurnData::prepare()
{
    QFileInfo f;
    ifstream fin;
    std::string s;
    QString sysid;

    m_oISOOutput.clear();
    m_oProcess->setProgram("/bin/bash");

    m_iProgress = 0;
    fin.open("/etc/kylin-build");
    if (fin.is_open())
    {
        std::getline(fin, s);
        sysid = QString::fromStdString(s);
    }
    if (sysid.isEmpty()) sysid = _("KylinOS");

    LOGGER->info(QString("光驱为：%1").arg(cloneCDROM->display()));
    if (cloneCDROM->mediumType().startsWith("CD")) {
        if (cloneCDROM->display().contains("aigo") || cloneCDROM->display().contains("DVDRAM GUE1N")) {
            LOGGER->info("CD盘， 光驱：aigo或HL-DT-ST DVDRAM GUE1N，使用xorriso命令刻录");
            f.setFile("/bin/xorriso");
        }
        else
            f.setFile("/bin/cdrecord");
    }
    else if (cloneCDROM->mediumType().contains("DVD+R DL"))
        f.setFile("/bin/xorriso");
    else
        f.setFile("/bin/growisofs");

    if ( (cloneCDROM->mediumType().compare("DVD+R") == 0)  && cloneCDROM->display().contains("ASUS SDRW-08U1MT") ) {
        LOGGER->info(QString("光驱为：ASUS SDRW-08U1MT，光盘为DVD+R 使用xorriso"));
        f.setFile("/bin/xorriso");
    }

    if ( cloneCDROM->display().contains("DVDRAM GH24NSD5") ) {
        LOGGER->info(QString("光驱为：HL-DT-ST DVDRAM GH24NSD5，光盘为DVD+R 使用xorriso"));
        f.setFile("/bin/xorriso");
    }

    if (!f.exists() || !f.isExecutable())
    {
        LOGGER->error(_("There is no %1 program or %1 cannot execute."
                "Please check the cdrecord, growisofs and xorriso is "
                "exists or not, and give the right permissions"
                ".%2 exiting...")
              .arg(f.absoluteFilePath())
              .arg("KylinBurner"));
        return false;
    }
    connect(this, SIGNAL(cancel(bool)), MODAL, SLOT(cancelEnable(bool)));
    m_bCreateISO = cloneCDROM->settingCreateISO();
    if (m_bCreateISO)
    {
        qDebug()<<__func__<<__LINE__<<m_bCreateISO;
        f.setFile("/bin/mkisofs");
        if (!f.exists() || !f.isExecutable())
        {
            LOGGER->error(_("There is no %1 program or %1 cannot execute."
                    "Please check the mkisofs is exists or not, and give "
                    "the right permissions.%2 exiting...")
                  .arg(f.absoluteFilePath())
                  .arg("KylinBurner"));
            return false;
        }
        m_oISOOutput = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
        m_oISOOutput.append("/").append(cloneCDROM->settingVolumnID()).append(".iso");
        f.setFile(m_oISOOutput);
        if (f.exists())
        {

            if (!EXEC->question(_("Create ISO") + " - " + _("Already Exists"),
                                _("There is already have the iso file named %1,"
                                  "replace it or not?").arg(f.fileName()))) {
                return false;
            }
            if (f.isFile()) QFile::remove(f.absoluteFilePath());
            else { QDir dir(f.absoluteFilePath()); dir.removeRecursively(); }
        }
    }
    PROGRESS;
    MODAL->show();
    m_oCreateISO = QString("mkisofs -o %1 -r -R -J -joliet-long -no-pad -no-iso-translate ").arg(m_oISOOutput);
    m_oMkisofs = QString("genisoimage -r -R -J -joliet-long -no-pad -no-iso-translate ");
    m_oMkisofs.append(QString("-A \"%1\" ").arg(_("KylinBurner")));
    m_oCreateISO.append(QString("-A \"%1\" ").arg(_("KylinBurner")));
    m_oArguments << "-c";
    if (cloneCDROM->mediumType().startsWith("CD"))
    {
        m_oCdrecord = QString("cdrecord -v driveropts=burnfree -nopad ");
        setValue(++m_iProgress, m_oIcon, _("Prepare to burn data to CD."));
    }
    else if (cloneCDROM->mediumType().contains("DVD+R DL"))
    {
        setValue(++m_iProgress, m_oIcon, _("Prepare to burn data to DVD+R."));
    }
    else
    {
        m_oGrowisofs = QString("growisofs -J -r -R -joliet-long -v -gui ");
        m_oGrowisofs.append(QString("-A \"%1\" ").arg(_("KylinBurner")));
        setValue(++m_iProgress, m_oIcon, _("Prepare to burn data to DVD."));
    }
    if (!sysid.isEmpty())
    {
        m_oMkisofs.append(QString("--sysid \"%1\" ").arg(sysid));
        m_oGrowisofs.append(QString("--sysid \"%1\" ").arg(sysid));
    }
    return m_oKeep;
}

bool ProcessBurnData::config()
{
    qDebug()<<__LINE__<<__func__<<cloneCDROM->settingCloseSession();
    if (cloneCDROM->mediumStatus() == DataMedium::MEDIUM_EMPTY)
    {
        m_oMkisofs.append(QString("-p \"%1\" ").arg(cloneCDROM->settingPreparer()));
        m_oCreateISO.append(QString("-p \"%1\" ").arg(cloneCDROM->settingPreparer()));
        m_oGrowisofs.append(QString("-p \"%1\" ").arg(cloneCDROM->settingPreparer()));
        m_oMkisofs.append(QString("-P \"%1\" ").arg(cloneCDROM->settingPublisher()));
        m_oCreateISO.append(QString("-P \"%1\" ").arg(cloneCDROM->settingPublisher()));
        m_oGrowisofs.append(QString("-P \"%1\" ").arg(cloneCDROM->settingPublisher()));
        m_oMkisofs.append(QString("-copyright \"%1\" ").arg(cloneCDROM->settingCopyright()));
        m_oCreateISO.append(QString("-copyright \"%1\" ").arg(cloneCDROM->settingCopyright()));
        m_oGrowisofs.append(QString("-copyright \"%1\" ").arg(cloneCDROM->settingCopyright()));
    }

    m_oMkisofs.append(QString("-V \"%1\" ").arg(cloneCDROM->settingVolumnID()));
    m_oCreateISO.append(QString("-V \"%1\" ").arg(cloneCDROM->settingVolumnID()));
    m_oGrowisofs.append(QString("-V \"%1\" ").arg(cloneCDROM->settingVolumnID()));

    if (cloneCDROM->settingSpeed())
    {
        m_oMkisofs.append(QString("-speed=%1 ").arg(cloneCDROM->settingSpeed()));
        m_oGrowisofs.append(QString("-speed=%1 ").arg(cloneCDROM->settingSpeed()));
        m_oCdrecord.append(QString("speed=%1 ").arg(cloneCDROM->settingSpeed()));
    }
    m_oCdrecord.append("-eject ");
    if (!cloneCDROM->settingCloseSession()) {
        m_oCdrecord.append("-multi ");
        m_oCdXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close off -joliet on -commit -eject")
                            .arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
    } else {
        m_oGrowisofs.append("-dvd-compat ");
        m_oCdXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close on -joliet on -commit -eject")
                            .arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
    }
    setValue(++m_iProgress, m_oIcon, _("Prepare to start burn data."));
    return m_oKeep;
}

bool ProcessBurnData::working()
{
    if (m_bGreateThan2GB)
    {
        m_oMkisofs.append("-allow-limited-size ");
        m_oCreateISO.append("-allow-limited-size ");
        m_oGrowisofs.append("-allow-limited-size ");

        LOGGER->info(QString("单个文件>2G, m_oGrowisofs  = %2").arg(m_oGrowisofs));
        m_oGrowisofs.clear();
        m_oGrowisofs = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -joliet on ").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        LOGGER->info(QString("单个文件>2G, 重置命令后m_oGrowisofs  = %2").arg(m_oGrowisofs));

        if (!cloneCDROM->settingCloseSession()) {
            m_oGrowisofs.append(" -close off -commit -eject");
            LOGGER->info(QString("单个文件>2G, 不关盘，m_oGrowisofs  = %2").arg(m_oGrowisofs));
        } else {
            m_oGrowisofs.append(" -close on -commit -eject");
            LOGGER->info(QString("单个文件>2G, 关盘，m_oGrowisofs  = %2").arg(m_oGrowisofs));
        }

    }

    if (m_oSize > 4UL * 1024UL * 1024UL * 1024UL)
    {
        m_oMkisofs.append("-udf ");
        m_oCreateISO.append("-udf ");
        m_oGrowisofs.append("-udf ");

        LOGGER->info(QString("总文件>4G, m_oGrowisofs  = %2").arg(m_oGrowisofs));
        m_oGrowisofs.clear();
        m_oGrowisofs = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -joliet on ").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        LOGGER->info(QString("总文件>4G, 重置命令后m_oGrowisofs  = %2").arg(m_oGrowisofs));

        if (!cloneCDROM->settingCloseSession()) {
            m_oGrowisofs.append(" -close off -commit -eject");
            LOGGER->info(QString("总文件>4G, 不关盘，m_oGrowisofs  = %2").arg(m_oGrowisofs));
        } else {
            m_oGrowisofs.append(" -close on -commit -eject");
            LOGGER->info(QString("总文件>4G, 关盘，m_oGrowisofs  = %2").arg(m_oGrowisofs));
        }
    }

    m_iCopied = 0;
    //disable cancel btn before copy
    emit cancel(false);
    connect(m_root, &DataDirectory::copied, this, &ProcessBurnData::slotsCopy);
    m_root->copy();
    if(!DataFile::isCopySuccess) {
        DataFile::isCopySuccess = true;
        LOGGER->info("(ProcessBurnData::working) 拷贝文件失败");
        return false;
    }

    if (m_bVerficationData) {
        DirOptUtils *diropt  = new DirOptUtils;
        diropt->getFileListUnderDir1(m_oTempPath);
        diropt->testPrintMap();
        diropt->generateCheckFile();
        delete diropt;
    }

    if (m_bCancel)
    {
        return false;
    }

    if (m_bCreateISO)
    {
        m_oCreateISO.append(m_odestination);
        m_oArguments << m_oCreateISO;
        m_oProcess->setArguments(m_oArguments);
        for (int i = 0; i < m_oArguments.size(); ++i)
        {
            qDebug() << QString("Arg.%1 - %2").arg(i + 1).arg(m_oArguments.at(i));
        }
        qDebug() << "";

        cloneCDROM->updateCDROMBurnStart(true);
        m_oProcess->start();
        while (m_oProcess->state() != QProcess::NotRunning){
            QCoreApplication::processEvents();
        }
        if(!m_oKeep) return false;
        m_bCreateISO = false;
    }

    if (m_bCancel) {
        qDebug()<<__func__<<__LINE__<<m_bCancel;
        return false;
    }

    // 非空盘刻录需要先卸载光盘
    if (m_bAppendBurn) {
        m_umountError = DataCDROM::umountMedium(cloneCDROM->device());
        if (!m_umountError) {
            ProcessLsof lsofPro;
            if (lsofPro.checkDevice(cloneCDROM)) {
                const QList<ProcessLsof::Process>& apps = lsofPro.usingApplications();
                if (apps.count() > 0) {
                    m_umountErrorStr = _("Device '%1' is used by the '%2' application! Please try again later").arg(cloneCDROM->display()).arg(lsofPro.joinProcessNames(apps));
                }
            }

            LOGGER->info(QString("(ProcessBurnData::working) cdrom run umount: ").arg(m_umountErrorStr));
            return false;
        }
    }

    m_oArguments.clear();
    m_oArguments << "-c";

    /* 先按光盘类型、光盘类型+光驱 给刻录命令配置参数 */
    if (cloneCDROM->mediumType().startsWith("CD"))
    {
        if (m_bAppendBurn)
        {
            m_oMSINFO = QString("cdrecord -msinfo dev=%1").arg(cloneCDROM->device());
            m_oArguments << m_oMSINFO;
            m_oProcess->setArguments(m_oArguments);
            m_oProcess->start();
            while (m_oProcess->state() != QProcess::NotRunning)
                QCoreApplication::processEvents();
            m_bAppendBurn = false;
            m_oArguments.clear();
            m_oArguments << "-c";
            m_oMkisofs.append(QString("-C \"%1\"").arg(m_oMSINFO));
            m_oMkisofs.append(" ");
            m_oMkisofs.append(QString("-M \"%1\"").arg(cloneCDROM->device()));
            m_oMkisofs.append(" ");
        }

        m_oMkisofs.append(m_odestination);
        m_oMkisofs.append(" ");
        m_oCdrecord.append(QString("dev=%1 -").arg(cloneCDROM->device()));

        if (cloneCDROM->display().contains("aigo") || cloneCDROM->display().contains("DVDRAM GUE1N"))
        {
            m_oArguments.clear();
            m_oArguments << "-c";
            m_oArguments << m_oCdXorriso;
        }
        else
        {
            m_oArguments << QString("%1 | %2").arg(m_oMkisofs).arg(m_oCdrecord);
        }
    }
    else if( (cloneCDROM->mediumType().compare("DVD+R") == 0) && cloneCDROM->display().contains("ASUS SDRW-08U1MT") )
    {
        if (!cloneCDROM->settingCloseSession())
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -joliet on -close off -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        else
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -joliet on -close on -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        m_oArguments << m_oXorriso;
    }
    else if (cloneCDROM->mediumType().contains("DVD+R DL"))
    {
        if (!cloneCDROM->settingCloseSession())
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close off -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        else
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close on -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());

        LOGGER->info(_("the command for xorriso is: %1").arg(m_oXorriso));
        m_oArguments << m_oXorriso;
    }
    else
    { // 非DL与CD盘
        if (m_bAppendBurn)
        {
            if (!m_bGreateThan2GB && !(m_oSize > 4UL * 1024UL * 1024UL * 1024UL))
            { // 使用growisofs进行追加刻录
                m_oGrowisofs.append(QString("-M %1 \"%2\"").arg(cloneCDROM->device()).arg(m_odestination));
            }
        }
        else
        {
            if (!m_bGreateThan2GB && !(m_oSize > 4UL * 1024UL * 1024UL * 1024UL))
            { // 使用growisofs进行追加刻录
                m_oGrowisofs.append(QString("-Z %1 \"%2\"").arg(cloneCDROM->device()).arg(m_odestination));
            }
        }
        m_oArguments << m_oGrowisofs;
    }

    /* 后处理特殊光驱 */

    if (cloneCDROM->display().contains("DVDRAM GH24NSD5")) {
        m_oArguments.clear();
        m_oArguments << "-c";

        if (!cloneCDROM->settingCloseSession())
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close off -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());
        else
            m_oXorriso = QString("xorriso -dev %1 -map \"%2\" \"%3\" -volid \"%4\" -close on -commit -eject").arg(cloneCDROM->device()).arg(m_odestination).arg("/").arg(cloneCDROM->settingVolumnID());

        LOGGER->info(QString("特殊光驱HL-DT-ST，the command for xorriso is: %1").arg(m_oXorriso));
        m_oArguments << m_oXorriso;
    }

    m_oProcess->setArguments(m_oArguments);
    LOGGER->info(_("Argument setted for %1:").arg(m_oProcess->program()));
    for (int i = 0; i < m_oArguments.size(); ++i)
    {
        LOGGER->info(_("Arg.%1 - %2").arg(i + 1).arg(m_oArguments.at(i)));
        qDebug() << QString("Arg.%1 - %2").arg(i + 1).arg(m_oArguments.at(i));
    }

    m_oProcess->start();
    while (m_oProcess->state() != QProcess::NotRunning)
        QCoreApplication::processEvents();
    return m_oKeep;
}

bool ProcessBurnData::worked()
{
    if (m_bCancel) return false;
    if (QProcess::NormalExit != m_oProcess->exitStatus()) return false;
    return m_oKeep;
}

void ProcessBurnData::slotsStart()
{
    cancel(false);
}

void ProcessBurnData::slotsOutput()
{
    qreal si;
    qreal t;
    qreal tmp;
    qreal basic;
    QString output;
    QStringList s;

    output = m_oProcess->readAllStandardOutput();

    if (m_bCancel)
        m_oProcess->kill();
    if (m_bAppendBurn)
    {
        m_oMSINFO.clear();
        m_oMSINFO = output.trimmed();
    }

    //CD光盘命令刻录数据返回的打印信息
    basic = 99 - m_iProgress;

    if (output.contains("Performing OPC"))
    {
        setValue(++m_iProgress, m_oIcon, _("Performing OPC"));
        cancel(false);
    }
    if (output.startsWith("\rTrack"))
    {
        // 例子：Track 01:   57 MB written (fifo 100%) [buf 100%]  10.2x.
        // CD盘进度条有问题：不能计算刻录进度，只有已刻录容量没有总容量
        s = output.split(" ");
        for (int i = 0; i < s.size(); ++i)
        {
            if (s.at(i).isEmpty())
            {
                s.takeAt(i);
                --i;
            }
        }
        si = s.at(2).toDouble();

        t = s.at(4).toDouble();
        if (t==0) t = m_oNewSize;
        if (s.size() > 5)
        {
            tmp = m_iProgress + (si / t * basic);
            if(tmp >= 99) tmp = 99;
            setValue(tmp, m_oIcon,_("Writing track %1 speed %2 written %3 %4.")
                     .arg(s.at(1)).arg(s.last()).arg(s.at(2)).arg(s.at(3)));
        }
    }

    if (output.contains("Fixating"))
        setValue(99, m_oIcon, _("Fixating(Will wait minutes)"));
    LOGGER->info(output);
}

void ProcessBurnData::slotsError()
{
    QString output = m_oProcess->readAllStandardError();

    QList<QString> errorInfoList;
    errorInfoList << "Input/output error" << "OPC failed." << "FATAL:" << ":-["
                  << "xorriso : aborting" << "seems to be mounted!" << "target is busy"
                  << "Cannot open busy device";
    bool isErrorInfo = false;

    foreach (QString index, errorInfoList) {
        if(output.contains(index)){
            m_iErrorInfoNum++;
            m_oKeep = false;
            isErrorInfo = true;
            LOGGER->info(QString("file:[%1] line:[%2] : m_oKeep =  [%3] m_iErrorInfoNum = [%4]").arg(__FILE__).arg(__LINE__).arg(m_oKeep).arg(m_iErrorInfoNum));
            break;
        }
    }

    if (output.contains("target is busy") || output.contains("Cannot open busy device")) {
        m_umountError = false;
    }

    if (output.contains("Input/output error")) {
        m_lastErrorMsg = QString(_("Input/output error. Disc may be damaged, please clean or replace a disc and try again."));
    }

    if (output.contains(":-(")) {
        LOGGER->info(QString("[%1] [%2] 发现错误： [%3]").arg(__func__).arg(__LINE__).arg(output));

        if (m_oFlag && output.contains(":-( unable to reload tray")){
            m_oKeep = true;
            LOGGER->info(QString("[%1] [%2] 出现 :-( unable to reload tray, 不认为是错误输出 设置m_oKeep = [%3]").arg(__func__).arg(__LINE__).arg(m_oKeep));
        } else if (m_oKeep && output.contains(":-( next session would cross 4GB")) {
            m_oKeep = false;
            LOGGER->info(QString("file:[%1] line:[%2] : m_oKeep =  [%3]").arg(__FILE__).arg(__LINE__).arg(m_oKeep));
            m_lastErrorMsg = QString(_("Not allowed when the disc data exceeds 4GB after burning data."));
        }  else {
            m_oKeep = false;
            LOGGER->info(QString("file:[%1] line:[%2] : m_oKeep =  [%3]").arg(__FILE__).arg(__LINE__).arg(m_oKeep));
        }
    }

    if(output.contains("No such device")) {
        /** CD盘刻录镜像时，光驱拔出后报错，进程需等待10分钟结束，不会立即结束，用户感知刻录镜像
         * 失败后不弹框，所以直接杀死进程
         **/
        if (m_oProcess->state() != QProcess::NotRunning)
        {
            m_oKeep = false;
            LOGGER->info(_("An error occurs when the CD is removed during data burning. The image burning process is terminated."));
            m_oProcess->kill();
        }
    }

    int basic;
    if(cloneCDROM->mediumType().contains("DVD+R DL") ||
            (cloneCDROM->mediumType().contains("CD") && cloneCDROM->display().contains("aigo")) ||
            ((cloneCDROM->mediumType().contains("CD")) && (cloneCDROM->display().contains("DVDRAM GUE1N"))) ||
            ((cloneCDROM->mediumType().compare("DVD+R") == 0) && cloneCDROM->display().contains("ASUS SDRW-08U1MT")) ||
            (cloneCDROM->mediumType().contains("DVDRAM GH24NSD5")) ||
            ((cloneCDROM->mediumType().contains("DVD+RW") && m_bGreateThan2GB)))
    {
        basic = 90 - m_iProgress;
        //xorriso : UPDATE : Writing:     362880s   17.7%   fifo 100%  buf  98%    4.0xD
        if(output.startsWith("xorriso : UPDATE : Writing"))
        {
            QStringList subStrList = output.split(" ");
            for(int i = 0; i < subStrList.size(); ++i)
            {
                if(subStrList.at(i).contains("%"))
                {
                    qreal outputProgress = subStrList.at(i).left(subStrList.at(i).indexOf("%")).toDouble();
                    qreal realProgress = m_iProgress + (outputProgress / 100.0 * basic);

                    if (realProgress >= 90) {
                        realProgress = 90;
                    }

                    emit setValue(realProgress, m_oIcon, _("medium is burning..."));
                    break;
                }
            }
        }
        else if(output.contains("xorriso : UPDATE : Closing track/session")) //DVD+R DL在Closing track/session需要一点时间，使用1s的定时器做一个假的进度条
        {
            if(!m_oProgressBarTimer_DVD->isActive())
            {
                m_iProgress = 90;
                m_oProgressBarTimer_DVD->start(1000);
            }
        }
        else if(output.contains("completed successfully"))
        {
            m_oProgressBarTimer_DVD->stop();
            disconnect(m_oProgressBarTimer_DVD, SIGNAL(timeout()), this, SLOT(slotsProcessBarDVD()));
            setValue(99, m_oIcon, _("completed successfully."));
        }
    }
    else  //除DVD-R DL盘后的其它DVD盘
    { 
        if (m_bCreateISO) {
            basic = 60 - m_iProgress;
        } else {
            basic = 99 - m_iProgress;
        }

        if (output.contains("done, estimate")){

            //例子:8.96% done, estimate finish Wed Mar  2 15:10:17 2022\n
            output = output.left(output.indexOf('%'));
            qreal outputProgress = output.toDouble();

            outputProgress = (outputProgress / 100.00) * basic;
            qreal realProgress = outputProgress + m_iProgress;

            if (realProgress > 99){
                realProgress = 99;
            }

            if (m_bCreateISO){
                emit setValue(realProgress, m_oIcon, _("Building ISO %1").arg(m_oISOOutput));
            }else{
                if (m_fSpeed > 0){
                    emit setValue(realProgress, m_oIcon, _("Burning by speed %1x").arg(m_fSpeed));
                }
            }
        }

        if (output.contains("Current Write Speed")){
            QStringList subStrList = output.split(" ");
            subStrList = subStrList.last().split("x");
            m_fSpeed = subStrList.first().toDouble();
        }

        QList<QString> processInfoList;
        processInfoList << "flushing cache" << "closing track" << "closing session";

        foreach (QString index, processInfoList) {
            if(output.contains(index)){
                emit setValue(99, m_oIcon, _(index));
            }
        }

        if(output.contains("reloading tray")){
            m_oFlag = true;
            LOGGER->info(QString("[%1] [%2]  run return value: reloading tray 设置m_oFlag = [%3]").arg(__func__).arg(__LINE__).arg(m_oFlag));
        }
    }

    if(isErrorInfo){
        Logger::instance()->error(output);
    }else{
        Logger::instance()->info(output);
    }

}

void ProcessBurnData::slotsFinished(int code, QProcess::ExitStatus status)
{
    DataCDROM *cdrom;
    cdrom = (DataCDROM *)m_oCDROM;

    LOGGER->info(_("Exit code is %1, status : %2, m_oKeep : %3, m_umountError : %4").arg(code).arg(status).arg(m_oKeep).arg(m_umountError));
    if (m_bAppendBurn && cloneCDROM->mediumType().contains("CD")) return;
    if (!m_bCreateISO) setValue(99, m_oIcon, _("Burn Data"));
    if (QProcess::NormalExit == status && 0 == code)
    {
        qDebug()<<__func__<<__LINE__<<m_bCreateISO;
        if(m_bCreateISO)
        {
            //点击“创建镜像”
            LOGGER->info( QString("file:[%1] line:[%2] : slotsFinished() create ISO success.").arg(__FILE__).arg(__LINE__) );
            return;
        } else {
            LOGGER->info(QString("file:[%1] line:[%2]: slotsFinished() burner data success.").arg(__FILE__).arg(__LINE__) );
        }
    }
    else
    {
        if(m_bCreateISO)
        {
            //点击“创建镜像”
            LOGGER->info( QString("file:[%1] line:[%2] : slotsFinished() create ISO failed.").arg(__FILE__).arg(__LINE__) );
            LOGGER->error( QString("file:[%1] line:[%2] : slotsFinished() create failure. [%3]").arg(__FILE__).arg(__LINE__).arg(m_oProcess->errorString()) );
            m_oCreateIsoLog.ouputCreateResult(cloneCDROM->display(), cloneCDROM->mDisplay(), true==m_oKeep);
            m_oKeep = false;
            return;
        } else {
            LOGGER->error( QString("file:[%1] line:[%2] : slotsFinished() Medium burn data failure. [%3]").arg(__FILE__).arg(__LINE__).arg(m_oProcess->errorString()) );
        }

        if (m_oFlag && m_oKeep && (1 == code)){
            qDebug() << __LINE__ << __func__ << "出现 :-( unable to reload tray, 不认为是错误输出 m_oFlag = " << m_oFlag << " m_oKeep = " << m_oKeep << "code = " << code;
            m_oKeep = true;
        } else {
            m_oKeep = false;
        }

        LOGGER->error( QString("file:[%1] line:[%2] : slotsFinished() Medium burn data failure. [%3]").arg(__FILE__).arg(__LINE__).arg(m_oProcess->errorString()) );

    }

    cloneCDROM->updateCDROMBurnStart(false);
    emit g_user_signal->noMedium(cdrom);


    if(m_isSpecialMachine==true)
    {
        auditburner->set("burner-os-auditlog-name",auditlogpath);
        m_oBurnDataLog.outputResult(cloneCDROM->display(), cloneCDROM->mediumType(), m_oProcessName, true==m_oKeep);
    }
    else
    {
        auditburner->set("burner-os-auditlog-name","");
    }
}

void ProcessBurnData::slotsCopy(QString src, QString des)
{
    int basic;

    if(m_isSpecialMachine==true){
        auditburner->set("burner-os-auditlog-name",auditlogpath);
        m_oBurnDataLog.appendFile(src);                         //待刻录的源文件
    }else{
        auditburner->set("burner-os-auditlog-name","");
    }

    if (m_bCreateISO) {
        basic = 30 - m_iProgress;
    }else {
        basic = 50 - m_iProgress;
    }

    ++m_iCopied;

    qreal v = ((m_iCopied * 1.0) / (m_ototal * 1.0));
    v = v * basic;
    m_iProgress += v;

    emit setValue(m_iProgress, m_oIcon, _("%1").arg(src));
    LOGGER->debug(_("Copied %1 to %2").arg(src).arg(des));
}


void ProcessBurnData::slotsProcessBarDVD()
{
    m_iProgress += 1;
    if (m_iProgress > 99) m_iProgress = 99;
    setValue(m_iProgress, m_oIcon, _("closing track"));
}

void ProcessBurnData::slotsRemoveDisc(QString dev)
{
    if(dev == cloneCDROM->device()) {
        if(m_oProcess->state() != QProcess::NotRunning) {
            qDebug() << __func__ << __LINE__ << dev << "被拔出，杀死刻录数据进程";
            LOGGER->info(QString("[%1] [%2] : %3 被拔出，杀死刻录数据进程").arg(__func__).arg(__LINE__).arg(dev));
            m_oProcess->kill();
        }
    }
}

