//
// Created by uos on 2022/2/16.
//

#include "Process.h"
#include <QProcess>
#include <QDebug>
#include <QThread>

bool Process::spawnCmd(const QString &cmd, const QStringList &args)
{
    QProcess process;
    process.setProgram(cmd);
    process.setArguments(args);
    // Merge stdout and stderr of subprocess with main Process.
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.start();
    // Wait for Process to finish without timeout.
    process.waitForFinished(-1);
    return (process.exitStatus() == QProcess::NormalExit &&
            process.exitCode() == 0);
}

bool Process::spawnCmd(const QString &cmd, const QStringList &args, QString &output)
{
    QString err;
    return spawnCmd(cmd, args, output, err);
}

bool Process::spawnCmd(const QString &cmd, const QStringList &args, QString &output, QString &err)
{
    QProcess process;
    process.setProgram(cmd);
    process.setArguments(args);

    process.start();
    // Wait for Process to finish without timeout.
    process.waitForFinished(-1);
    output += process.readAllStandardOutput();
    err += process.readAllStandardError();
    QProcess::ExitStatus procStatus = process.exitStatus();
    int exitCode = process.exitCode();

    if (procStatus == QProcess::NormalExit && exitCode == 0) {
        return true;
    }
    return false;
}

bool Process::spawnCmd(const QString &cmd, const QStringList &args, QString &output, QString &err, int tryCount)
{
    int loop_num = 0;
    while (loop_num++ < tryCount) {
        bool result = spawnCmd(cmd, args, output, err);
        if (result) {
            return true;
        }

        qDebug() << err;
        qDebug() << "try again!!!!!";
        QThread::sleep(1);
    }

    return false;
}

bool Process::spawnCmd(const QString &cmd, QString& output, QString& err)
{
    QProcess process;
    process.start(cmd);
    // Wait for Process to finish without timeout.
    process.waitForFinished(-1);
    output += process.readAllStandardOutput();
    err += process.readAllStandardError();
    QProcess::ExitStatus procStatus = process.exitStatus();
    int exitCode = process.exitCode();

    if (procStatus == QProcess::NormalExit && exitCode == 0) {
        return true;
    }

    return false;
}

bool Process::spawnSubCmd(const QString &mainCmd, const QStringList &mainArgs,
                          const QString &subCmd, const QStringList &subArgs, QString &output, QString &err)
{
    // eg: echo dm | jfs_debugfs /dev/sdd1
    // mainCmd: jfs_debugfs /dev/sdd1,  subCmd: echo dm
    // eg: cat /etc/os-version |grep MajorVersion
    // mainCmd: grep MajorVersion,  subCmd: cat /etc/os-version
    QProcess mainProc;
    QProcess subProc;
    subProc.setStandardOutputProcess(&mainProc);
    subProc.start(subCmd, subArgs);
    mainProc.start(mainCmd, mainArgs);

    // Wait for Process to finish without timeout.
    subProc.waitForFinished(-1);
    mainProc.waitForFinished(-1);

    output += mainProc.readAllStandardOutput();
    err += mainProc.readAllStandardError();
    QProcess::ExitStatus procStatus = mainProc.exitStatus();
    int exitCode = mainProc.exitCode();

    if (procStatus == QProcess::NormalExit && exitCode == 0) {
        return true;
    }
    return false;
}
