#include "processgetiso.h"
#include "src/frame/logger.h"
#include "src/po/translation.h"
#include "src/data/datacdrom.h"
#include "src/view/modaldialog.h"
#include "src/view/execdialog.h"
#include "src/frame/signals.h"
#include "src/frame/auditlog.h"
#include <kysdk/kysdk-system/libkysysinfo.h>

#include <QFileInfo>
#include <QDir>

ProcessGetISO::ProcessGetISO(void *src, void *des, QObject *parent) :
    ProcessBasic(parent),
    m_oSource(src),
    m_oDestination(des),
    m_iProgress(0)
{
    DataCDROM *srcCdrom = static_cast<DataCDROM *>(m_oSource);
    m_oDeviceBlock = srcCdrom->device();

    LOGGER->registerName(this, _("PROCESS_GI"));
    m_oProcessName = _("Get ISO");

    emit title(_("Getting ISO"));
    emit setRange(0, 100);
    emit setValue(0);
}

bool ProcessGetISO::prepare()
{
    QFileInfo fileInfo;

    connect(this, SIGNAL(cancel(bool)), MODAL, SLOT(cancelEnable(bool)));

    fileInfo.setFile("/bin/mkisofs");
    if (!fileInfo.exists())
    {
        LOGGER->error(_("Cannot find program <%1>.").arg(fileInfo.fileName()));
        emit setValue(1, QIcon::fromTheme("dialog-error-symbolic"),_("Cannot find program <%1>.").arg(fileInfo.fileName()));
        return false;
    }

    if (!fileInfo.isExecutable())
    {
        LOGGER->error(_("Program %1 is not executable file.").arg(fileInfo.fileName()));
        emit setValue(1, QIcon::fromTheme("dialog-error-symbolic"), _("Program %1 is not executable file.").arg(fileInfo.fileName()));
        return false;
    }

    m_oProcess->setProgram(fileInfo.fileName());
    emit setValue(++m_iProgress, m_oIcon, _("Preparing get iso file."));

    DataCDROM *des = static_cast<DataCDROM *>(m_oDestination);
    fileInfo.setFile(des->device());
    QString output = fileInfo.absolutePath();
    output.append("/");

    DataCDROM *src = static_cast<DataCDROM *>(m_oSource);
    if (src->mediumMountPoint().isEmpty())
    {
        LOGGER->error(_("Medium in CDROM %1 donot been mounted.").arg(src->display()));
        return false;
    }
    output.append(src->settingVolumnID());
    output.append(".iso");

    fileInfo.setFile(output);
    if (fileInfo.exists())
    {
        if (!EXEC->question(_("Get ISO") + " - " + _("Already Exists"),
                           _("There is already have the iso file named %1,"
                             "replace it or not?").arg(fileInfo.fileName())))
        {
            return false;
        }

        if (fileInfo.isFile()) {
            QFile::remove(fileInfo.absoluteFilePath());
        }else{
            QDir dir(fileInfo.absoluteFilePath());
            dir.removeRecursively();
        }

        LOGGER->debug(_("File %1 exists.").arg(fileInfo.absoluteFilePath()));
    }

    PROGRESS;
    MODAL->show();

    m_oArguments << "-o" << fileInfo.absoluteFilePath();

    m_oArguments << "-J" << "-r" << "-R" << "-joliet-long" << "-no-iso-translate"
                 << "-gui" << "-v" << "-ldots" << "-no-split-symlink-fields"
                 << "-no-cache-inodes" << "-full-iso9660-filenames";
    m_oArguments << "-A" << _("KylinBurner");

    m_oArguments << "-V" << src->settingVolumnID().trimmed();
    LOGGER->debug(_("Volumn ID : %1").arg(m_oArguments.last()));
    emit setValue(++m_iProgress, m_oIcon, _("Volumn ID %1").arg(m_oArguments.last()));

    m_oArguments << "-p" << src->settingPreparer().trimmed();
    LOGGER->debug(_("Preparer : %1").arg(m_oArguments.last()));
    emit setValue(++m_iProgress, m_oIcon, _("Preparer %1").arg(m_oArguments.last()));

    m_oArguments << "-P" << src->settingPublisher().trimmed();
    LOGGER->debug(_("Publisher : %1").arg(m_oArguments.last()));
    emit setValue(++m_iProgress, m_oIcon, _("Publisher %1").arg(m_oArguments.last()));

    m_oArguments << "-copyright" << src->settingCopyright().trimmed();
    LOGGER->debug(_("Copyright : %1").arg(m_oArguments.last()));
    emit setValue(++m_iProgress, m_oIcon, _("Copyright %1").arg(m_oArguments.last()));

    m_oArguments << src->mediumMountPoint();

    return true;
}

void ProcessGetISO::slotsError()
{
    int v = 0;
    qreal basic = 99 - m_iProgress;
    QString output = m_oProcess->readAllStandardError();
    bool isErrorMsg = false;

    if (output.contains("Input/output error")) {
        m_oKeep = false;
        m_lastErrorMsg = QString(_("Bad sector detected, please clean or replace a disc and try again."));
        isErrorMsg = true;
    }

    if (output.contains("done, estimate")) // 2.50% done, estimate finish Tue Feb  2 17:15:15 2021
    {
        output = output.left(output.indexOf('%'));
        v = output.toDouble();
        v = (v / 100.00) * basic;
        emit setValue(v, m_oIcon, _("Getting ISO"));
    }

    if(isErrorMsg){
        LOGGER->error(output);
    }else{
        LOGGER->info(output);
    }
}

void ProcessGetISO::slotsFinished(int errorCode, QProcess::ExitStatus status)
{
    AuditLog getIsoLog;

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

    DataCDROM *src = (DataCDROM*)m_oSource;
    DataCDROM *dest = (DataCDROM*)m_oDestination;

    if (m_isSpecialMachine == true) {
        auditburner->set("burner-os-auditlog-name",auditlogpath);
        getIsoLog.outputCopyResult(src->mediumMountPoint(), dest->display(), dest->mediumType(), m_oProcessName, true==m_oKeep);
    } else {
        auditburner->set("burner-os-auditlog-name","");
    }

    LOGGER->info(_("Exit code is %1, status : %2").arg(errorCode).arg(status));
    if (QProcess::NormalExit == status && 0 == errorCode)
    {
        LOGGER->info( QString("slotsFinished() line[%1] : get ISO success.").arg(__LINE__) );
    }
    else
    {
        m_oKeep = false;
        LOGGER->error( QString("slotsFinished() line[%1] : get ISO failure: %2").arg(__LINE__).arg(m_oProcess->errorString()) );
    }
}

ProcessGetISO::~ProcessGetISO()
{
}
