#include "processearse.h"
#include "src/frame/logger.h"
#include "src/po/translation.h"
#include "src/data/datacdrom.h"
#include "src/view/modaldialog.h"
#include "src/frame/auditlog.h"
#include "src/frame/signals.h"
#include <QFileInfo>
#include <QDebug>

ProcessEarse::ProcessEarse(void *cdrom, QObject *parent) :
    ProcessBasic(parent),
     m_oCDROM(cdrom),
     m_oPro(new QTimer(this))
{
   // m_isSpecialMachine=kdk_system_is_zyj();
    auditburner=new QGSettings("org.ukui.kylinburner");
    auditlogpath="/var/log/kylin-burner/os_audit.log";
    m_isSpecialMachine=auditburner->get("burneraudit-isrunning").toBool();
    m_oCloneCDROM = ((DataCDROM *)cdrom)->clone();
    m_oDeviceBlock = m_oCloneCDROM->device();
    m_iValue = 0;
    LOGGER->registerName(this, _("PROCESS_EARSE"));
    MODAL->show();
    title(_("Earsing"));
    m_oProcessName = _("Earse");
    setRange(0, 100);
    setValue(0);
    connect(m_oPro, SIGNAL(timeout()), this, SLOT(slotsProgress()));
    connect(g_user_signal, &GlobalUserSignal::removeDisc, this, &ProcessEarse::slotsRemoveDisc);
    m_oPro->setInterval(1000);
}

bool ProcessEarse::prepare()
{
    QFileInfo f;

    PROGRESS;
    MODAL->show();
    connect(this, SIGNAL(cancel(bool)), MODAL, SLOT(cancelEnable(bool)));

    m_oTimer->start(500);

    if (m_oCloneCDROM->mediumType().contains("CD"))
        f.setFile("/bin/cdrecord");
    else
        f.setFile("/bin/xorriso");
    if (!f.exists() || !f.isExecutable())
    {
        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_oProcess->setProgram(f.fileName());
    return true;
}

bool ProcessEarse::config()
{
    if (m_oCloneCDROM->mediumType().contains("CD"))
    {
        m_oCloneCDROM->umount();
        m_oArguments << "blank=fast"
                     << "driveropts=burnfree"
                     << QString("dev=%1").arg(m_oCloneCDROM->device())
                     << "-v"
                     << "-eject";
        setValue(m_iValue++, m_oIcon, _("Umount CD, and prepare to blank CD."));
    }
    else
    {
        m_oCloneCDROM->umount();
        m_oArguments << "-dev" << m_oCloneCDROM->device() << "-format" << "full";
    }
    g_user_signal->setDeviceBusyStatus(m_oDeviceBlock,true);
    return m_oKeep;
}

bool ProcessEarse::worked()
{
    m_oCloneCDROM->eject();
    return m_oKeep;
}

void ProcessEarse::slotsOutput()
{
    // CD 光盘进行擦除操作
    QString output;

    output = m_oProcess->readAllStandardOutput();
    qDebug() << __func__ << __LINE__  << "output : " << output;
    info(QString("[%1] [%2] output: %3").arg(__func__).arg(__LINE__).arg(output));
    if (output.contains("Input/output error")) {
        m_oKeep = false;
    } else if(output.contains("Errno:")) {
        m_oKeep = false;
    }

    if (output.contains("Performing OPC"))
    {
        cancel(false);
        setValue(m_iValue++, m_oIcon, _("Performing OPC"));
        return;
    } else if (output.contains("Fixating")) {
        setValue(99, m_oIcon, _("Fixating(Will wait minutes)"));
        return;
    }

    if (!m_oPro->isActive()) {
        m_oPro->start();
    }
}

void ProcessEarse::slotsError()
{
    QString eraseCmdOutput;
    static int eraseValue = 0;
    eraseCmdOutput = m_oProcess->readAllStandardError();
    qDebug() << __func__ << __LINE__  << "error : " << eraseCmdOutput;
    info(eraseCmdOutput);
    if(eraseCmdOutput.contains("Beginning to format medium")){
        eraseValue = 1;
        cancel(false);
    }else if(eraseCmdOutput.contains("Formatting done")){
        eraseValue = 100;
    }else if(eraseCmdOutput.contains("Device or resource busy")){
        this->error("Device or resource busy");
        m_oKeep = false;
        return;
    } else if(eraseCmdOutput.contains("xorriso : aborting")) {
        m_oKeep = false;
        return;
    } else if(eraseCmdOutput.contains("Formatting")){
        DataCDROM *cdrom = (DataCDROM*)m_oCDROM;
        if(m_oCloneCDROM->mediumType().contains("DVD-RW")){
            int currentValue = -1;
            currentValue = (int)eraseCmdOutput.split(' ').at(7).mid(0,3).toDouble();
            if((currentValue - eraseValue) < 2)
                eraseValue = currentValue;
        }else{
            if(eraseValue +5 >= 99)
                eraseValue = 99;
            else
                eraseValue += 5;
        }
    }

    setValue(eraseValue, m_oIcon, _("earsing...."));
}

void ProcessEarse::slotsFinished(int code, QProcess::ExitStatus status)
{
    if (m_oPro->isActive()) m_oPro->stop();
    g_user_signal->setDeviceBusyStatus( m_oDeviceBlock,false);

    info(_("Exit code is %1, status : %2").arg(code).arg(status));
    setValue(99, m_oIcon, _("earsing...."));
    if (QProcess::NormalExit == status && 0==code)
    {
        setValue(100, m_oIcon, _("Burn Data"));
        info( QString("slotsFinished() line[%1] : earse Medium success.").arg(__LINE__) );
        m_oCloneCDROM->eject();
    }
    else
    {
        m_oKeep = false;
        error( QString("slotsFinished() line[%1] : earse Medium failure. %2").arg(__LINE__).arg(m_oProcess->errorString()) );
    }
    if(m_isSpecialMachine==true){
        auditburner->set("burner-os-auditlog-name",auditlogpath);
        eraseLog.outputResult(m_oCloneCDROM->display(), m_oCloneCDROM->mediumType(), m_oProcessName, true==m_oKeep);
    } else {
        auditburner->set("burner-os-auditlog-name","");
    }
}

void ProcessEarse::slotsProgress()
{
    if (++m_iValue < 99)
        setValue(m_iValue, m_oIcon, _("Blanking..."));
}

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

ProcessEarse::~ProcessEarse()
{
    //info(QString("[%1] [%2] : 析构函数").arg(__func__).arg(__LINE__));
    if (auditburner) {
        delete auditburner;
        auditburner = nullptr;
    }
    //info(QString("[%1] [%2] : 准备析构m_oCloneCDROM").arg(__func__).arg(__LINE__));
    if (m_oCloneCDROM) {
        delete m_oCloneCDROM;
        m_oCloneCDROM = nullptr;
        //info(QString("[%1] [%2] : 已析构m_oCloneCDROM").arg(__func__).arg(__LINE__));
    }
    //info(QString("[%1] [%2] : 析构函数结束").arg(__func__).arg(__LINE__));
}
