/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#include <QtTest>

#include "CMakeProjectManager.h"

class TestCMakeProjectManager : public QObject {
    Q_OBJECT
private:
    QDir tempDir;
    bool testStatus;

    void testFile(QString camitkFileBaseName) {
        testStatus = false;

        // Create temporary dir and copy camiTKFileBaseName
        QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/CamiTKExtensionCheck_" + QDateTime::currentDateTime().toString("yyyyMMddHHmmss") + "/" + camitkFileBaseName;
        QVERIFY(QDir().mkpath(tempPath));
        tempDir.setPath(tempPath);

        QString camitkFileFullPath = tempDir.filePath(camitkFileBaseName + ".camitk");
        QVERIFY(QFile::copy(":/" + camitkFileBaseName + ".camitk", camitkFileFullPath));

        CMakeProjectManager manager(camitkFileFullPath);
        manager.setStages({CMakeProjectManager::Check_System, CMakeProjectManager::Generate_Source_Files, CMakeProjectManager::Configure_CMake, CMakeProjectManager::Build_Project});
        qDebug() << "Testing" << camitkFileBaseName << "in" << tempDir.path();
        QVERIFY2(manager.success(), "Failed to initialize temporary directory tree");

        // connect signal to follow progress
        connect(&manager, &CMakeProjectManager::stageStarted, this, [ = ](const QString & stage) {
            qDebug().noquote().nospace() << "Starting stage \"" << stage << "\"...";
        });

        connect(&manager, &CMakeProjectManager::stageFinished, this, [ = ](const QString & stage, bool success, const QString & output) {
            qDebug().noquote().nospace() << "Stage \"" << stage << "\" finished.";
            qDebug().noquote().nospace() << "Status: " << ((success) ? "[OK]" : "[FAILED]");
            qDebug().noquote().nospace() << "Output:\n" << output;
            QVERIFY2(success, QString("Failed in stage: " + stage).toUtf8());
        });

        connect(&manager, &CMakeProjectManager::allStagesFinished, this, [ =, this ](bool status) {
            testStatus = status;
            QVERIFY(status);
        });
        manager.start();
    }

private slots:

    // initTestCase() : called once before any tests are run.

    // called before each test function
    void init() {
        QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/CamiTKExtensionCheck_" + QDateTime::currentDateTime().toString("yyyyMMddHHmmss");
        QVERIFY(QDir().mkpath(tempPath));
        tempDir.setPath(tempPath);
    }

    // called after each test function.
    void cleanup() {
        if (testStatus) {
            tempDir.removeRecursively();
        }
        else {
            qDebug().noquote().nospace() << "Temporary directory not removed: " << tempDir.path();
        }
    }

    void testStandard1() {
        testFile("parametersStandard");
    }

    void testStandard2() {
        testFile("thresholdExtensionStandard");
    }

    void testStandard3() {
        testFile("stdActions");
    }

    void testHotPlug1() {
        testFile("parametersHotPlug");
    }

    void testHotPlug2() {
        testFile("thresholdExtensionHotPlug");
    }

    void testHotPlug3() {
        testFile("multiActionsHotPlug");
    }

    // cleanupTestCase() : called once after all tests have been run.
};

// Manual coverage:
// cd build
// ./bin/test-transformengine
// or ctest -R test-transformengine-1
// lcov --capture --directory . --output-file coverage.info
// genhtml coverage.info --output-directory coverage_report
// firefox coverage_report/index.html

QTEST_MAIN(TestCMakeProjectManager)

#include "TestCMakeProjectManager.moc"