#include "commandline_parser.h"

#include <QDir>
#include <QSettings>
#include <QDebug>
#include <QFile>

CommandLineParser::CommandLineParser()
  : m_repositoryUrl("https://git.mimbach49.de/GerhardHoffmann")
  , m_plugInDir("/usr/lib/")
  , m_plugInName("libCAslave.so")
  , m_workingDir("/opt/app/tools/atbupdate/")
  , m_dryRun("false")
  , m_noUpdatePsaHardware("false")
  , m_showYoctoVersion("false")
  , m_showYoctoInstallStatus("false")
  , m_showExtendedVersion("false")
  , m_iniFileName("ATBUpdateTool.ini")
  , m_alwaysDownloadConfig("false")
  , m_alwaysDownloadDC("false")
  , m_repositoryUrlOption(
        QCommandLineOption(
            QStringList() << "repository-url" << "repository-url",
            QCoreApplication::translate("main", "Where to find a customer repository."),
            QCoreApplication::translate("main", "directory")))
  , m_iniFileDirectoryOption(
        QCommandLineOption(
            QStringList() << "ini-directory" << "ini-directory",
            QCoreApplication::translate("main", "Where to find an ini-file."),
            QCoreApplication::translate("main", "directory")))
  , m_iniFileNameOption(
        QCommandLineOption(
            QStringList() << "ini-filename" << "ini-filename",
            QCoreApplication::translate("main", "Name of ini-file."),
            QCoreApplication::translate("main", "file")))
  , m_pluginDirectoryOption(
        QCommandLineOption(
            QStringList() << "plugin-directory" << "plugin-directory",
            QCoreApplication::translate("main", "Where to find dc-plugin."),
            QCoreApplication::translate("main", "directory")))
  , m_pluginNameOption(
        QCommandLineOption(
            QStringList() << "plugin-name" << "plugin-name",
            QCoreApplication::translate("main", "Name of dc-plugin."),
            QCoreApplication::translate("main", "directory")))
  , m_noDownloadOption(
        QCommandLineOption(
            "no-psa-hardware-update",
            QCoreApplication::translate("main", "Do not update the PSA firmware (json, device-controller).")))
  , m_alwaysDownloadConfigOption(
        QCommandLineOption(
            "always-download-config",
            QCoreApplication::translate("main", "Always download the (json-)configs to DC).")))
  , m_alwaysDownloadDCOption(
        QCommandLineOption(
            "always-download-dc",
            QCoreApplication::translate("main", "Always download the dc-bin-file to DC).")))
  , m_workingDirectoryOption(
        QCommandLineOption(
            QStringList() << "working-directory" << "working-directory",
            QCoreApplication::translate("main", "working directory of update-script."),
            QCoreApplication::translate("main", "directory")))
  , m_dryRunOption(
        QCommandLineOption(
            QStringList() << "d" << "dry-run",
            QCoreApplication::translate("main", "Start ATBUpdateTool in dry-run-mode. No actual actions.")))
  , m_extendedVersionOption(
        QCommandLineOption(
            QStringList() << "V" << "extended-version",
            QCoreApplication::translate("main", "Show extended version (including last git commit).")))
  , m_yoctoVersionOption(
        QCommandLineOption(
            QStringList() << "y" << "yocto-version",
            QCoreApplication::translate("main", "Show yocto version of ATBUpdateTool.")))
  , m_yoctoInstallStatusOption(
        QCommandLineOption(
            QStringList() << "Y" << "yocto-install",
            QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."))) {
    configure();
}

void CommandLineParser::configure() {
    m_parser.setApplicationDescription("Download tool for downloading device controller firmware, printer json-files and executing opkg-commands.");
    m_parser.addHelpOption();
    m_parser.addVersionOption();

    m_repositoryUrlOption.setDefaultValue("https://git.mimbach49.de/GerhardHoffmann");
    m_parser.addOption(m_repositoryUrlOption);

    m_iniFileDirectoryOption.setDefaultValue(QCoreApplication::applicationDirPath());
    m_parser.addOption(m_iniFileDirectoryOption);

    m_iniFileNameOption.setDefaultValue("ATBUpdateTool.ini");
    m_parser.addOption(m_iniFileNameOption);

    m_pluginDirectoryOption.setDefaultValue("/usr/lib/");
    m_parser.addOption(m_pluginDirectoryOption);

    m_pluginNameOption.setDefaultValue("libCAslave.so");
    m_parser.addOption(m_pluginNameOption);

    m_alwaysDownloadConfigOption.setDefaultValue("false");
    m_parser.addOption(m_alwaysDownloadConfigOption);

    m_alwaysDownloadDCOption.setDefaultValue("false");
    m_parser.addOption(m_alwaysDownloadDCOption);

    m_noDownloadOption.setDefaultValue("false");
    m_parser.addOption(m_noDownloadOption);

    m_workingDirectoryOption.setDefaultValue("/opt/app/tools/atbupdate/");
    m_parser.addOption(m_workingDirectoryOption);

    m_dryRunOption.setDefaultValue("false");
    m_parser.addOption(m_dryRunOption);

    m_extendedVersionOption.setDefaultValue("false");
    m_parser.addOption(m_extendedVersionOption);

    m_yoctoVersionOption.setDefaultValue("false");
    m_parser.addOption(m_yoctoVersionOption);

    m_yoctoInstallStatusOption.setDefaultValue("false");
    m_parser.addOption(m_yoctoInstallStatusOption);
}

void CommandLineParser::readSettings() {
    QString const iniFileDir = m_parser.value(m_iniFileDirectoryOption);
    QString const iniFileName = m_parser.value(m_iniFileNameOption);
    m_iniFileName = QDir::cleanPath(iniFileDir + QDir::separator() + iniFileName);

    qCritical() << __PRETTY_FUNCTION__ << " iniFileDir" << iniFileDir;
    qCritical() << __PRETTY_FUNCTION__ << "iniFileName" << m_iniFileName;

    if (!m_iniFileName.isEmpty()) {
        if (QFile(m_iniFileName).exists()) {
            QSettings settings(m_iniFileName, QSettings::IniFormat);
            QStringList keys = settings.allKeys();
            for (QString const &key: keys) {
                QVariant v = settings.value(key);

                qCritical() << __PRETTY_FUNCTION__
                            << key << " -> " << v.toString();

                if (key.contains("repository-url")) {
                    m_repositoryUrl = v.toString();
                } else
                if (key.contains("plugin-directory")) {
                    m_plugInDir = v.toString();
                } else
                if (key.contains("working-directory")) {
                    m_workingDir = v.toString();
                } else
                if (key.contains("dry-run")) {
                    m_dryRun = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("extended-version")) {
                    m_showExtendedVersion = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("no-psa-hardware-update")) {
                    m_noUpdatePsaHardware = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("always-download-config")) {
                    m_alwaysDownloadConfig = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("always-download-dc")) {
                    m_alwaysDownloadDC = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("yocto-install")) {
                    m_showYoctoInstallStatus = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("yocto-version")) {
                    m_showYoctoVersion = (v.toBool() ? "true" : "false");
                } else
                if (key.contains("plugin-name")) {
                    m_plugInName = v.toString();
                } else {
                    qCritical() << __PRETTY_FUNCTION__
                                << key << " -> (UNKNOWN) " << v.toString();
                }
            }
        } else {
            qCritical() << __PRETTY_FUNCTION__ << "iniFileName" << m_iniFileName
                        << "DOES NOT EXIST";
        }
    }
}

QString CommandLineParser::repositoryUrl() {
    if (m_parser.isSet(m_repositoryUrlOption)) {
        m_repositoryUrl = m_parser.value(m_repositoryUrlOption);
    }
    return m_repositoryUrl;
}

QString CommandLineParser::plugInDir() {
    if (m_parser.isSet(m_pluginDirectoryOption)) {
        m_plugInDir = m_parser.value(m_pluginDirectoryOption);
    }
    return m_plugInDir;
}

QString CommandLineParser::plugInName() {
    if (m_parser.isSet(m_pluginNameOption)) {
        m_plugInName = m_parser.value(m_pluginNameOption);
    }
    return m_plugInName;
}

QString CommandLineParser::workingDir() {
    if (m_parser.isSet(m_workingDirectoryOption)) {
        m_workingDir = m_parser.value(m_workingDirectoryOption);
    }
    return m_workingDir;
}

bool CommandLineParser::dryRun() {
    if (m_parser.isSet(m_dryRunOption)) {
        m_dryRun = m_parser.value(m_dryRunOption);
    }
    return m_dryRun == "false" ? false : true;
}

bool CommandLineParser::noUpdatePsaHardware() {
    if (m_parser.isSet(m_noDownloadOption)) {
        m_noUpdatePsaHardware = m_parser.value(m_noDownloadOption);
    }
    return m_noUpdatePsaHardware == "false" ? false : true;
}

bool CommandLineParser::yoctoVersion() {
    if (m_parser.isSet(m_yoctoVersionOption)) {
        m_showYoctoVersion = m_parser.value(m_yoctoVersionOption);
    }
    return m_showYoctoVersion == "false" ? false : true;
}

bool CommandLineParser::yoctoInstallStatus() {
    if (m_parser.isSet(m_yoctoInstallStatusOption)) {
        m_showYoctoInstallStatus = m_parser.value(m_yoctoInstallStatusOption);
    }
    return m_showYoctoInstallStatus == "false" ? false : true;
}

bool CommandLineParser::extendedVersion() {
    if (m_parser.isSet(m_extendedVersionOption)) {
        m_showExtendedVersion = m_parser.value(m_extendedVersionOption);
    }
    return m_showExtendedVersion == "false" ? false : true;
}

bool CommandLineParser::alwaysDownloadConfig() {
    if (m_parser.isSet(m_alwaysDownloadConfigOption)) {
        m_alwaysDownloadConfig = m_parser.value(m_alwaysDownloadConfigOption);
        qCritical() << "m_alwaysDownloadConfigOption IS SET" << m_alwaysDownloadConfig;
    }
    qCritical() << "m_alwaysDownloadConfig" << m_alwaysDownloadConfig;
    return m_alwaysDownloadConfig == "false" ? false : true;
}

bool CommandLineParser::alwaysDownloadDC() {
    if (m_parser.isSet(m_alwaysDownloadDCOption)) {
        m_alwaysDownloadDC = m_parser.value(m_alwaysDownloadDCOption);
    }
    return m_alwaysDownloadDC == "false" ? false : true;
}