
// copyright marazmista @ 29.11.2014

#include "execbin.h"
#include "globalStuff.h"

#include <QLabel>
#include <QFileDialog>

ExecBin::ExecBin() : QObject(),
    tab(new QWidget()),
    p(new QProcess(this)),
    output(new QPlainTextEdit()),
    cmd(new QPlainTextEdit()),
    mainLay(new  QVBoxLayout()),
    btnLay(new QHBoxLayout()),
    lStatus(new QLabel()),
    btnSave(new QPushButton())

{
    setupTab();

    connect(p,SIGNAL(readyReadStandardOutput()),this,SLOT(execProcessReadOutput()));
    connect(p,SIGNAL(finished(int)),this,SLOT(execProcesFinished()));
    connect(p,SIGNAL(started()),this,SLOT(execProcesStart()));
    connect(btnSave,SIGNAL(clicked()),this,SLOT(saveToFile()));
}

void ExecBin::setupTab() {
    output->setReadOnly(true);
    cmd->setReadOnly(true);
    cmd->setMaximumHeight(60);
    cmd->setFont(QFont("monospace", 8));
    output->setFont(QFont("monospace", 8));
    btnLay->setAlignment(Qt::AlignRight);
    QFont f;
    f.setBold(true);
    lStatus->setFont(f);
    p->setProcessChannelMode(QProcess::MergedChannels);


    this->btnSave->setText(tr("Save output to file"));

    // just two labels out of nowhere, forget it
    QLabel *l1 = new QLabel();
    l1->setText(tr("Command"));
    QLabel *l2 = new QLabel();
    l2->setText(tr("Output"));

    btnLay->addWidget(lStatus);
    btnLay->addWidget(btnSave);

    mainLay->addWidget(l1);
    mainLay->addWidget(cmd);
    mainLay->addWidget(l2);
    mainLay->addWidget(output);
    mainLay->addLayout(btnLay);
    tab->setLayout(mainLay);
}

void ExecBin::runBin(const QString &cmd) {
    p->start(cmd);
    this->cmd->setPlainText(p->processEnvironment().toStringList().join(" ") +" "+ cmd);
}

void ExecBin::setEnv(const QProcessEnvironment &env) {
    this->p->setProcessEnvironment(env);
}

void ExecBin::execProcessReadOutput() {
    QString o = this->p->readAllStandardOutput();

    if (!o.isEmpty())
        this->output->appendPlainText(o);
}

void ExecBin::execProcesStart() {
    this->lStatus->setText(tr("Process state: running"));
}

void ExecBin::execProcesFinished() {
    if (!this->logData.logFilename.isEmpty() && this->logData.log.count() > 0) {
        QFile f(logData.logFilename);
        f.open(QIODevice::WriteOnly);
        f.write(this->logData.log.join("\n").toLatin1());
        f.close();
        this->logData.log.clear();
    }

    this->lStatus->setText(tr("Process state: not running"));
}

void ExecBin::saveToFile() {
        QString filename = QFileDialog::getSaveFileName(nullptr, tr("Save"), QDir::homePath()+"/output_"+this->name);
        if (!filename.isEmpty()) {
            QFile f(filename);
            f.open(QIODevice::WriteOnly);
            f.write(this->output->toPlainText().toLatin1());
            f.close();
        }
}

QProcess::ProcessState ExecBin::getExecState() {
    return this->p->state();
}

void ExecBin::appendToLog(const QString &data) {
    this->logData.log.append(data);
}

void ExecBin::setLogFilename(const QString &name) {
    this->logData.logFilename = name;
}
