/*******************************************************************************
 * Copyright (c) 2017, Kyle Robbertze (AIMS, South Africa)
 *
 * This project is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License version 3 as 
 * published by the Free Software Foundation.
 *
 * It is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this project. If not, see <http://www.gnu.org/licenses/>.
 *
 *    Description:  Main GUI widget
 * 
 *        Created:  23/02/2017 11:50:04
 *       Compiler:  g++
 * 
 *         Author:  Kyle Robbertze (kr), kyle@aims.ac.za
 *******************************************************************************/

#include "main_window.h"

#include <QFile>
#include <QMessageBox>
#include <QProcess>
#include <QPushButton>
#include <QScrollBar>
#include <QTextStream>

#include "ui_main_window.h"

MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::onAboutTriggered);
    connect(ui->actionQuit, &QAction::triggered, qApp, &QApplication::quit);
    connect(ui->verifyButton, &QPushButton::clicked, this, &MainWindow::onVerifyClicked);

}

void MainWindow::onVerifyClicked() {
    ui->verifyButton->setEnabled(false);
    ui->statusProgress->setEnabled(true);
    ui->statusProgress->setValue(0);
    QFile md5File { m_root + "/md5sum.txt" };
    if (!md5File.open(QIODevice::ReadOnly)) {
        QMessageBox::critical(this, tr("Error"), tr("%1 cannot be read. Unable to continue")
                .arg(md5File.fileName()));
        qWarning("verify: %s cannot be read", md5File.fileName().toStdString()
                .c_str());
        ui->statusProgress->setEnabled(false);
        ui->verifyButton->setEnabled(true);
        return;
    }
    ui->statusText->setPlainText(tr("Verifying..."));
    QTextStream in { &md5File };
    QStringList file;
    while (!in.atEnd()) {
        file.append(in.readLine());
    }
    ui->statusProgress->setMaximum(file.size());
    QProcess process;
    int i = 0;
    bool isIdentical = true;
    for (auto line : file) {
        QStringList components = line.split("  ");
        QString expectedMd5 = components.at(0);
        QFile checkFile { m_root + "/" + components.at(1) };
        ui->statusBar->showMessage(tr("Checking %1").arg(checkFile.fileName()));
        process.start("md5sum " + checkFile.fileName());
        process.waitForFinished();
        if (process.exitStatus() != QProcess::NormalExit || 
                process.exitCode()) {
            appendStatus(tr("WARNING: Unable to calculate the MD5 Sum. "
                        "md5sum has exit code %1").arg(process.exitCode()));
            qWarning("verify: md5sum exited with code %d", process.exitCode());
            isIdentical = false;
            ui->statusProgress->setValue(i++);
            continue;
        }
        QString actualMd5 = QString(process.readAllStandardOutput()
                .toStdString().c_str()).split("  ").at(0);
        if (actualMd5 != expectedMd5) {
            isIdentical = false;
            appendStatus(tr("WARNING: MD5 sums do not match for %1").arg(checkFile.fileName()));
            appendStatus(tr("Expected %1, but found %2").arg(expectedMd5, actualMd5));
        }
        ui->statusProgress->setValue(i++);
    }
    ui->statusBar->clearMessage();
    appendStatus("------------------");
    if (isIdentical)
        appendStatus(tr("MD5 sums match"));
    else
        appendStatus(tr("WARNING: MD5 sums do not match"));
    ui->statusProgress->setValue(i);
    ui->verifyButton->setEnabled(true);
}

void MainWindow::onAboutTriggered() {
    QMessageBox::about(this, "Hashcheck " HASHCHECK_VERSION, 
            tr("This project comes with NO WARRANTY, to the extent permitted "
                "by the law.You may redistribute it under the terms of the GNU "
                "General Public License version 3; see the file named LICENSE "
                "for details.\n\n"
                "Written by Kyle Robbertze"));
}

void MainWindow::appendStatus(QString text) {
    QString oldText { ui->statusText->toPlainText() };
    ui->statusText->setPlainText(oldText + "\n" + text);
    QScrollBar* sb { ui->statusText->verticalScrollBar() };
    sb->setValue(sb->maximum());
}
