//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/Model/Util/Path.cpp
//! @brief     Implements Helpers functions.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "GUI/Model/Util/Path.h"
#include "BAVersion.h"
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QMap>
#include <QStandardPaths>

namespace {

QMap<QString, QString> initializeCharacterMap()
{
    QMap<QString, QString> result;
    result["\\"] = "_backslash_";
    result["/"] = "_slash_";
    result["\""] = "_quote_";
    result["<"] = "_lessthan_";
    result[">"] = "_greaterthan_";
    result["|"] = "_pipe_";
    result["?"] = "_questionmark_";
    return result;
}

const QMap<QString, QString> invalidCharacterMap = initializeCharacterMap();

} // namespace


QString GUI::Path::withTildeHomePath(const QString& path)
{
#ifdef Q_OS_WIN
    return path;
#endif

    static const QString homePath = QDir::homePath();

    QFileInfo fi(QDir::cleanPath(path));
    QString outPath = fi.absoluteFilePath();
    if (outPath.startsWith(homePath))
        return "~" + outPath.mid(homePath.size());
    return path;
}

QString GUI::Path::getBornAgainVersionString()
{
    return QString::fromStdString(BornAgain::GetVersionNumber());
}

//! Returns valid file name to be saved on disk. This name is constructed from proposed_name
//! by replacing all special characters with text representation
//! \ backslash
//! / slash
//! " quote
//! < lessthan
//! > greaterthan
//! | pipe
//! ? questionmark
QString GUI::Path::getValidFileName(const QString& proposed_name)
{
    QString result = proposed_name;
    for (auto it = invalidCharacterMap.begin(); it != invalidCharacterMap.end(); ++it)
        result.replace(it.key(), it.value());
    return result;
}

//! Constructs the name of the file for intensity data.
QString GUI::Path::intensityDataFileName(const QString& itemName, const QString& prefix)
{
    return prefix + "_" + getValidFileName(itemName) + ".int";
}


//! parses version string into 2 numbers, returns true in the case of success
bool GUI::Path::parseVersion(const QString& version, int& major_num, int& minor_num)
{
    major_num = 0;
    minor_num = 0;
    bool success(true);
    QStringList nums = version.split(".");
    if (nums.size() != 2)
        return false;

    bool ok(false);
    major_num = nums.at(0).toInt(&ok);
    success &= ok;
    minor_num = nums.at(1).toInt(&ok);
    success &= ok;

    return success;
}

int GUI::Path::versionCode(const QString& version)
{
    int ba_major;
    int ba_minor;
    if (!parseVersion(version, ba_major, ba_minor))
        return -1;

    return ba_major * 100 + ba_minor;
}

//! Returns true if current BornAgain version match minimal required version
bool GUI::Path::isVersionMatchMinimal(const QString& version, const QString& minimal_version)
{
    return versionCode(version) >= versionCode(minimal_version);
}

//! Returns file directory from the full file path
QString GUI::Path::fileDir(const QString& fname)
{
    QFileInfo info(fname);
    if (info.exists())
        return info.dir().path();
    return "";
}

//! Returns base name of file.

QString GUI::Path::baseName(const QString& fname)
{
    QFileInfo info(fname);
    return info.baseName();
}
