/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2016 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
 *
 * 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 "ExtensionGenerator.h"

// includes from cepcoreschema
#include <Dependency.hxx>

// includes from STL
#include <iostream>
#include <memory>

// includes from Qt
#include <QFileInfo>
#include <QDir>
#include <QTextStream>

// local includes
#include "DependencyGenerator.h"

using namespace cepcoreschema;

static const QString testDataDirName = "testdata";

ExtensionGenerator::ExtensionGenerator(QString extensionsDirectory, QString licence, QString extensionType) {
    setExtensionsDirectory(extensionsDirectory);
    this->licence = licence;
    this->extensionType = extensionType;
}

ExtensionGenerator::~ExtensionGenerator() {
//    for (QVector<DependencyGenerator *>::iterator dep = dependencyGenerators.begin(); dep != dependencyGenerators.end(); dep++)
//        delete dep;

}

void ExtensionGenerator::setExtensionsDirectory(QString extensionsDirectory) {
    this->extensionsDirectory = extensionsDirectory;
}

void ExtensionGenerator::generateExtension() {
    QString directory;
    // A generate right subdirectory
    QDir currentDirectory;
    // 1 - get absolute path
    currentDirectory.cd(extensionsDirectory);
    // 2 - generate right name
    QString extensionDirName = this->name;
    extensionDirName = extensionDirName.simplified(); // change every whitespace (\t, \n, etc.) to single ASCII space
    extensionDirName = extensionDirName.replace( " ", "" ); // remove white spaces
    extensionDirName = extensionDirName.toLower(); // to lower case
    // 3 - go into subdirectory
    currentDirectory.mkdir(extensionDirName);
    currentDirectory.cd(extensionDirName);

    directory = currentDirectory.absolutePath();

    // B generate CMakeLists
    generateExtensionCMakeLists(directory);

    // C generate actions
    generateActionOrComponent(directory);

    // D generate cpp and h files
    writeHFile(directory);
    writeCFile(directory);

    // E generate test files
    generateTestDataFiles(directory, testDataDirName);
}

void ExtensionGenerator::generateExtensionCMakeLists(QString directory) {
    // Generate strings for dependencies
    QString extLibs  = DependencyGenerator::getExternalLibsString(this->dependencyGenerators);
    QString cepLibs =  DependencyGenerator::getCepLibsString(this->dependencyGenerators);
    QString neededComps = DependencyGenerator::getNeededComponentsString(this->dependencyGenerators);
    QString neededActions = DependencyGenerator::getNeededActionsString(this->dependencyGenerators);


    // Open the resources CMakeFile model
    QFile initFile(":/resources/CamiTKExtensionCMakeLists.txt.in");
    initFile.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream in(&initFile);

    // Set the right output file name
    QFileInfo cmakelistsOutFileInfo;
    cmakelistsOutFileInfo.setFile(directory, "CMakeLists.txt");
    QFile cmakelistsOutFile(cmakelistsOutFileInfo.absoluteFilePath());
    if (! cmakelistsOutFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QString msg = "Exception from cep file generation \n    Cannot write on file " + cmakelistsOutFileInfo.absoluteFilePath() + "\n";
        throw msg;
    }

    QTextStream out(&cmakelistsOutFile);
    QString text;
    do {
        text = in.readLine();
        text.replace(QRegExp("@EXTTYPELOW@"), extensionType.toLower());
        text.replace(QRegExp("@EXTTYPEHIGH@"), extensionType.toUpper());
        text.replace(QRegExp("@NEEDEDLIBS@"), extLibs);
        text.replace(QRegExp("@NEEDEDCEPLIBRARIES@"), cepLibs);
        text.replace(QRegExp("@NEEDEDCOMPEXT@"), neededComps);
        text.replace(QRegExp("@NEEDEDACTIONEXT@"), neededActions);
        text.replace(QRegExp("@EXTENSIONDESCRIPTION@"), this->description);
        out << text << endl;
    } while (! text.isNull());
    cmakelistsOutFile.close();
    initFile.close();

}

