#include "processburnudfdata.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 <QFileInfo>
#include <QDir>
#include <QCoreApplication>
#include <QStandardPaths>
#include <fstream>

ProcessBurnUDFData::ProcessBurnUDFData(void *root, void *cdrom, QObject *parent) :
    ProcessBasic(parent)
{
   // 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();
    DataCDROM *c;
    m_oCDROM = cdrom;
    m_oRoot = root;
    c = (DataCDROM *)cdrom;
    m_oDeviceBlock = c->device();
    m_fSpeed = 0;
    if (c->mediumStatus() == DataMedium::MEDIUM_EMPTY)
    {
        LOGGER->registerName(this, _("PROCESS_UDF_DATA"));
        title(_("Burning UDF Format Data"));
        m_oProcessName = _("Burn  UDF Format Data");
        m_bAppendBurn = false;
    }
    else
    {
        error(_("Media Not Empty,Not Burn UDF Format"));
        m_bAppendBurn = true;
    }
    MODAL->show();
    setRange(0, 100);
    setValue(0);
}

bool ProcessBurnUDFData::prepare()
{
    DataCDROM *cdrom;
    QFileInfo f;
    ifstream fin;
    std::string s;
    QString sysid;


    m_oProcess->setProgram("/bin/bash");
    cdrom = (DataCDROM *)m_oCDROM;

    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");


    f.setFile("/bin/growisofs");
    if (!f.exists() || !f.isExecutable())
    {
        error(_("There is no %1 program or %1 cannot execute."
                "Please check the cdrecord and growisofs 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)));

    g_user_signal->setDeviceBusyStatus(m_oDeviceBlock,true);
    PROGRESS;
    MODAL->show();

    m_oGrowisofs = QString("growisofs -udf -r  -v -gui ");
    m_oGrowisofs.append(QString("-A \"%1\" ").arg(_("KylinBurner")));
    setValue(++m_iProgress, m_oIcon, _("Prepare to burn UDF format 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 ProcessBurnUDFData::config()
{
    DataCDROM *cdrom;

    cdrom = (DataCDROM *)m_oCDROM;


    m_oGrowisofs.append(QString("-p \"%1\" ").arg(cdrom->settingPreparer()));
    m_oGrowisofs.append(QString("-copyright \"%1\" ").arg(cdrom->settingCopyright()));

    if (cdrom->settingSpeed())
        m_oGrowisofs.append(QString("-speed=%1 ").arg(cdrom->settingSpeed()));  
#if 0
    if (!cdrom->settingCloseSession())
    {
        m_oCdrecord.append("-multi ");
    }
    else
        m_oGrowisofs.append("-dvd-compat ");
#endif
    //-dvd-compat 加不加？
    //m_oGrowisofs.append("-dvd-compat ");
    setValue(++m_iProgress, m_oIcon, _("Prepare to start burn UFD format data."));
    return m_oKeep;
}

bool ProcessBurnUDFData::working()
{
    DataCDROM *cdrom;
    DataDirectory *root;

    cdrom = (DataCDROM *)m_oCDROM;
    root = (DataDirectory *)m_oRoot;
#if 1
    if (root->size() >= 4UL * 1024UL * 1024UL * 1024UL)
    {
        debug(_("%1 data size more than 2 GB, need allow-limited-size "
                "extension").arg(_("CreateISO")));

        m_oGrowisofs.append("-allow-limited-size ");
    }

#endif
    m_iCopied = 0;
    connect(root, SIGNAL(copied(QString,QString)), this, SLOT(slotsCopy(QString,QString)));
    root->copy();
    m_oTimer->start(500);
    if (m_bCancel) {
        g_user_signal->setDeviceBusyStatus(m_oDeviceBlock,false);
        return false;
    }

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

    m_oGrowisofs.append(QString("-Z %1 %2").arg(cdrom->device()).arg(root->destination()));
    m_oArguments << m_oGrowisofs;

    m_oProcess->setArguments(m_oArguments);
    info(_("Argument setted for %1:").arg(m_oProcess->program()));
    for (int i = 0; i < m_oArguments.size(); ++i)
    {
        debug(_("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 ProcessBurnUDFData::worked()
{
    if (m_bCancel) return false;
    if (QProcess::NormalExit != m_oProcess->exitStatus()) return false;
    return m_oKeep;
}

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

void ProcessBurnUDFData::slotsOutput()
{

    QString output;

    output = m_oProcess->readAllStandardOutput();
    debug(_("ProcessBurnUDFData::slotsOutput  output==[%1]").arg(output));
    if (m_bCancel)
        m_oProcess->kill();
}

void ProcessBurnUDFData::slotsError()
{
    qreal v;
    int basic ;
    QString output;
    QStringList ss;

    output = m_oProcess->readAllStandardError();
    info(_("ProcessBurnUDFData::slotsError  output==[%1]").arg(output));
#if 1
    if (output.contains("OPC failed."))
        m_oKeep = false;
    if (output.contains("Input/output error"))
        m_oKeep = false;
    if (output.contains(":-("))
        m_oKeep = false;
    if (output.contains("FATAL:"))
        m_oKeep = false;
    if (output.contains(":-["))
        m_oKeep = false;
    if (output.contains("error"))
        m_oKeep = false;

    basic = 97 - m_iProgress;
    if (output.contains("done, estimate"))
    {
        output = output.left(output.indexOf('%'));
        v = output.toDouble();
        v = (v / 100.00) * basic;
        m_iProgress += v;
        if (m_iProgress > 99) m_iProgress = 99;

        if (m_fSpeed > 0)
            setValue(m_iProgress, m_oIcon, _("Burning by speed %1x").arg(m_fSpeed));

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

    if (output.contains("flushing cache"))
    {
        setValue(97, m_oIcon, _("flushing cache"));
    }
    if (output.contains("writing lead-out"))
    {
        setValue(98, m_oIcon, _("writing lead-out"));
    }
    if (output.contains("reloading tray"))
    {
        setValue(99, m_oIcon, _("reloading tray"));
    }
#endif
}

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

    cdrom = (DataCDROM *)m_oCDROM;
    g_user_signal->setDeviceBusyStatus(m_oDeviceBlock,false);
    info(_("Exit code is %1, status : %2").arg(code).arg(status));


    if (QProcess::NormalExit == status && 0 == code)
    {
        setValue(100, m_oIcon, _("Burn Data"));
        cdrom->eject(false);
    }
    else
    {
        m_oKeep = false;
    }
    cdrom->eject();
    if(m_isSpecialMachine==true){
        auditburner->set("burner-os-auditlog-name",auditlogpath);
    m_oBurnUdfDataLog.outputResult(cdrom->display(), cdrom->mediumType(), m_oProcessName, true==m_oKeep);
    }else{
        auditburner->set("burner-os-auditlog-name","");
    }
}

void ProcessBurnUDFData::slotsCopy(QString src, QString des)
{
    qreal v;
    int basic;
    DataDirectory *root;

    root = (DataDirectory *)(m_oRoot);
    if(m_isSpecialMachine==true){
        auditburner->set("burner-os-auditlog-name",auditlogpath);
        m_oBurnUdfDataLog.appendFile(src);                      //待刻录的源文件
    }else{
        auditburner->set("burner-os-auditlog-name","");
    }
    if (m_bCreateISO) basic = 30 - m_iProgress;
    else basic = 50 - m_iProgress;
    ++m_iCopied;
    v = ((m_iCopied * 1.0) / (root->total() * 1.0));
    v = v * basic;
    m_iProgress += v;
    setValue(m_iProgress, m_oIcon, _("Copied %1 to %2").arg(src).arg(des));
    debug(_("Copied %1 to %2").arg(src).arg(des));
}

ProcessBurnUDFData::~ProcessBurnUDFData()
{}
