#ifndef WORKER_H_INCLUDED
#define WORKER_H_INCLUDED

#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QFile>
#include <QJsonObject>
#include <QHash>
#include <QMap>
#include <QDebug>
#include <QThread>
#include <QByteArray>
#include <QScopedPointer>

#include <optional>
#include <initializer_list>

#include "git/git_client.h"
#include "ismas/ismas_client.h"
#include "ismas/ApismClientForUpdate.h"
#include "utils.h"
#include "work_process_list.h"

#ifdef PTU5
#define SERIAL_PORT "ttymxc2"
#else
#define SERIAL_PORT "ttyUSB0"
#endif

/*
 Note:
    ! After U0002 immer ein CMD_SENDVERSION
    ! Only U0002 and U0003 finish the Update process.
    ! U0001: Update finished but not activated
    ! U0002: Update finished and activated
    ! U0003: Update finished but FAILed.
 */

#define _ISMAS_DONE                 "U0001" // 100%, Check: Resultcode: 0
#define _ISMAS_SET_WAIT_OK          "U0002" // empty WAIT-button (""), ResultCode: 0
#define _ISMAS_NO_UPDATE_NECESSARY  "M0100" // empty WAIT-button (""), ResultCode: 0
#define _ISMAS_FAILURE              "U0003" // FAIL
#define _ISMAS_CONTINUE             "U0010" // %-values: Update laeuft, Resultcodes entsprechend laufender Schritt
#define _ISMAS_RESET_WAIT           "ISMAS" // reset WAIT-button to "WAIT"
#define _ISMAS_TEST_TRIGGER         "U0099" // check the WAIT-button

#define _STARTED                                    (1)
#define _CHECK_ISMAS_TRIGGER                        (2)
#define _CHECK_SANITY                               (3)
#define _CHECK_SANITY_FAILURE                       (4)
#define _CHECK_SANITY_SUCCESS                       (5)
#define _REPOSITORY_RECOVERED_FAILURE               (6)
#define _REPOSITORY_RECOVERED_SUCCESS               (7)
#define _CHECK_REPOSITORY                           (8)
#define _CHECK_REPOSITORY_FAILURE                   (9)
#define _CHECK_REPOSITORY_SUCCESS                   (10)
#define _CLONE_REPOSITORY                           (11)
#define _CLONE_REPOSITORY_FAILURE                   (12)
#define _CLONE_REPOSITORY_SUCCESS                   (13)
#define _CHECKOUT_REPOSITORY                        (14)
#define _CHECKOUT_REPOSITORY_FAILURE                (15)
#define _CHECKOUT_REPOSITORY_SUCCESS                (16)
#define _INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER (17)
#define _INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER    (18)
#define _CHECK_ISMAS_TRIGGER_WRONG_VALUE            (19)
#define _CHECK_ISMAS_TRIGGER_SUCCESS                (20)
#define _CHECK_ISMAS_TRIGGER_FAILURE                (21)
#define _PULL_NEW_BRANCH                            (22)
#define _PULL_NEW_BRANCH_FAILURE                    (23)
#define _PULL_NEW_BRANCH_SUCCESS                    (24)
#define _CHECKOUT_BRANCH                            (25)
#define _CHECKOUT_BRANCH_FAILURE                    (26)
#define _CHECKOUT_BRANCH_SUCCESS                    (27)
#define _UPDATE_REPOSITORY                          (28)
#define _UPDATE_REPOSITORY_FAILURE                  (29)
#define _UPDATE_REPOSITORY_SUCCESS                  (30)
#define _CHECK_FOR_REPOSITORY_CHANGES               (31)
#define _CHECK_FOR_REPOSITORY_CHANGES_SUCCESS       (32)
#define _SYNC_CUSTOMER_REPOSITORY                   (33)
#define _SYNC_CUSTOMER_REPOSITORY_FAILURE           (34)
#define _SYNC_CUSTOMER_REPOSITORY_SUCCESS           (35)
#define _FILES_TO_UPDATE                            (36)
#define _CHECK_FOR_REPOSITORY_CHANGES_FAILURE       (37)
#define _EXEC_OPKG_COMMANDS                         (39)
#define _EXEC_OPKG_COMMAND_1                        (40)
#define _EXEC_OPKG_COMMAND_2                        (41)
#define _EXEC_OPKG_COMMAND_3                        (42)
#define _EXEC_OPKG_COMMAND_4                        (43)
#define _EXEC_OPKG_COMMAND_5                        (44)
#define _EXEC_OPKG_COMMAND_6                        (45)
#define _EXEC_OPKG_COMMAND_7                        (46)
#define _EXEC_OPKG_COMMAND_8                        (47)
#define _EXEC_OPKG_COMMAND_9                        (48)
#define _EXEC_OPKG_COMMAND_LAST                     (49)
#define _EXEC_OPKG_COMMAND_FAILURE                  (50)
#define _EXEC_OPKG_COMMAND_SUCCESS                  (51)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE             (59)
#define _FILES_TO_DOWNLOAD                          (60)
#define _DOWNLOAD_CASH_FILE                         (61)
#define _DOWNLOAD_CASH_FILE_FAILURE                 (62)
#define _DOWNLOAD_CASH_FILE_SUCCESS                 (63)
#define _DOWNLOAD_CONFIG_FILE                       (64)
#define _DOWNLOAD_CONFIG_FILE_FAILURE               (65)
#define _DOWNLOAD_CONFIG_FILE_SUCCESS               (66)
#define _DOWNLOAD_DEVICE_FILE                       (67)
#define _DOWNLOAD_DEVICE_FILE_FAILURE               (68)
#define _DOWNLOAD_DEVICE_FILE_SUCCESS               (69)
#define _DOWNLOAD_JSON_FILE                         (70)
#define _DOWNLOAD_JSON_FILE_FAILURE                 (71)
#define _DOWNLOAD_JSON_FILE_SUCCESS                 (72)
#define _DOWNLOAD_DEVICE_CONTROLLER                 (84)
#define _DOWNLOAD_DEVICE_CONTROLLER_FAILURE         (85)
#define _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS         (86)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE     (87)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS     (88)
#define _SAVE_LOGS                                  (92)
#define _SAVE_LOGS_FAILURE                          (93)
#define _SAVE_LOGS_SUCCESS                          (94)
#define _SEND_LAST_VERSION                          (95)
#define _UPDATE_FINALIZE                            (95)
#define _UPDATE_SUCCEEDED                           (96)
#define _UPDATE_FAILED                              (97)
#define _UPDATE_ACTIVATED                           (98)
#define _UPDATE_NOT_NECESSARY                       (99)
#define _FINISHED                                   (100)
#define _DEBUG                                      (1000)
#define _ERROR                                      (1001)
#define _NONE                                       (1002)

#define _SEND_LAST_VERSION_CORRECTION               (5)
#define _UPDATE_SUCCEEDED_CORRECTION                (4)
#define _UPDATE_FAILED_CORRECTION                   (3)
#define _UPDATE_ACTIVATED_CORRECTION                (2)
#define _UPDATE_NOT_NECESSARY_CORRECTION            (1)

#define ISMAS_UPDATE_REQUESTS                       (10)
#define CHECK_UPDATE_TRIGGER_SET                    "Check update trigger ..."

class Command;
class Update;
class MainWindow;
class hwinf;
class Worker : public QThread{
    Q_OBJECT

    int const m_customerNr;
    QString const m_customerNrStr;
    int const m_machineNr;
    int const m_zoneNr;
    QString const m_pluginDir;
    QString const m_pluginName;
    QString const m_workingDirectory;
    QString const m_branchName;
    QString const m_customerRepositoryPath;
    QString const m_customerRepository;
    bool const m_noUpdatePsaHardware;
    bool const m_alwaysDownloadConfig;
    bool const m_alwaysDownloadDC;
    bool const m_dryRun;
    QObject *m_parent;
    QString const m_serialInterface;
    QString const m_baudrate;
    IsmasClient m_ismasClient;
    GitClient m_gc;
    QStringList m_versionInfo;
    QString const m_osVersion;
    QString const m_atbqtVersion;
    QString const m_atbUpdateToolVersion;
    QString const m_cpuSerial;
    QString const m_pluginVersionATBDeciceController;
    QString const m_pluginVersionIngenicoISelf;
    QString const m_pluginVersionMobilisisCalc;
    QString const m_pluginVersionMobilisisCalcConfig;
    QString const m_pluginVersionPrmCalc;
    QString const m_pluginVersionPrmCalcConfig;
    QString const m_pluginVersionTcpZvt;

    int m_ismasUpdateRequests;
    QTimer m_summaryTimer;

    QStringList m_filesToUpdate;
    QStringList m_filesToDownload;
    bool m_updateProcessRunning;
    int m_displayIndex;
    bool m_clone = false;
    bool m_initialClone = false;
    bool m_repairClone = false;
    bool m_ismasTriggerActive = false;
    bool m_updateNotNecessary = false;
    bool m_automaticUpdate = false;
    bool m_pulledNewBranch = false;
    QStringList m_ismasTriggerStatusMessage;

    MainWindow *m_mainWindow;
    Command *m_dcDownloadFirmware;
    Command *m_dcDownloadJsonFiles;
    bool m_withoutIsmasDirectPort;
    QString m_apismVersion;

    WorkList m_workList;
    ApismClientForUpdate m_clForUpdate;

    bool executeOpkgCommand(QString opkgCommand);
    bool cleanUpOpkgCache();
    QString getOsVersion() const;
    QString getATBQTVersion() const;
    QString getATBUpdateToolVersion() const;
    QString getCPUSerial() const;
    QString getRaucVersion() const;
    QString getOpkgVersion() const;
    QString getPluginVersion(QString const &pluginFileName) const;
    QStringList getDCVersion() const;

    qint64 getFileSize(QString const &fileName) const;
    bool isRepositoryCorrupted();
    bool repairCorruptedRepository();

    int sendCloneAndCheckoutSuccess();
    int sendCloneAndCheckoutFailure();
    int sendIsmasTriggerFailure();
    int sendPullFailure();
    int sendFileUpdateFailure();
    int sendRsyncFailure();
    int sendLastVersionFailure();
    int sendSaveLogFilesFailure();
    int sendCustomerEnvironmentConfigurationFailed();
    int sendFoundFilesToUpdateSuccess();
    int sendUpdateSucceededAndActivated();
    int sendFinalResult();

    struct UpdateProcessRunning {
        Worker *m_worker;

        explicit UpdateProcessRunning(Worker *worker) : m_worker(worker) {
            m_worker->m_updateProcessRunning = true;
            // emit m_worker->disableExit();
            emit m_worker->enableExit();
            m_worker->startProgressLoop();
        }

        virtual ~UpdateProcessRunning() {

            if (m_worker->m_lastFailedUpdateStep == UPDATE_STEP::NONE) {
                if (m_worker->m_updateNotNecessary) {
                    QStringList lst = m_worker->m_ismasTriggerStatusMessage;
                    m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << (m_worker->ISMAS(lst) << UPDATE_STEP::UPDATE_NOT_NECESSARY));
                } else {
                    QStringList lst(QString(m_worker->smap[UPDATE_STEP::UPDATE_SUCCEEDED]));
                    m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << UPDATE_STEP::UPDATE_SUCCEEDED));
                    m_worker->setProgress(_UPDATE_SUCCEEDED);

                    lst = QStringList(QString(m_worker->smap[UPDATE_STEP::UPDATE_ACTIVATED]));
                    m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << UPDATE_STEP::UPDATE_ACTIVATED));
                    m_worker->setProgress(_UPDATE_ACTIVATED);

                    lst = QStringList(QString(m_worker->smap[UPDATE_STEP::FINISHED]));
                    m_worker->CONSOLE(lst) << UPDATE_STEP::FINISHED;
                    m_worker->setProgress(_FINISHED);
                }
            } else {
                // QStringList lst = m_worker->m_ismasTriggerStatusMessage;
                QStringList lst;
                UPDATE_STEP last = m_worker->m_lastFailedUpdateStep;
                if (m_worker->smap.contains(last)) {
                    lst << QString(" (last failed step: %1)").arg(m_worker->smap[last]);
                } else {
                    lst << QString(" (last failed step unknown: %1)").arg((int)(last));
                }
                m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << (m_worker->ISMAS(lst) << UPDATE_STEP::UPDATE_FAILED));
            }

            if (m_worker->m_automaticUpdate) {
                QStringList lst(QString(m_worker->smap[UPDATE_STEP::SEND_LAST_VERSION]));
                lst << "AUTOMATIC UPDATE";
                if (m_worker->m_updateNotNecessary) {
                    lst << "UPDATE NOT NECESSARY";
                }
                m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst)
                                     << UPDATE_STEP::SEND_LAST_VERSION));
            } else {
                QStringList lst(QString(m_worker->smap[UPDATE_STEP::SEND_LAST_VERSION]));
                m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst)
                                     << UPDATE_STEP::SEND_LAST_VERSION));
            }
            m_worker->stopProgressLoop();
            m_worker->m_updateProcessRunning = false;
            emit m_worker->enableExit();
            emit m_worker->restartExitTimer();
        }
    };

    friend struct UpdateProcessRunning;

public:
    enum class UPDATE_STEP {
        STARTED = _STARTED,
        CHECK_REPOSITORY = _CHECK_REPOSITORY,
        CHECK_REPOSITORY_SUCCESS = _CHECK_REPOSITORY_SUCCESS,
        CHECK_REPOSITORY_FAILURE = _CHECK_REPOSITORY_FAILURE,
        CHECK_SANITY = _CHECK_SANITY,
        CHECK_SANITY_SUCCESS = _CHECK_SANITY_SUCCESS,
        CHECK_SANITY_FAILURE = _CHECK_SANITY_FAILURE,
        REPOSITORY_RECOVERED_SUCCESS = _REPOSITORY_RECOVERED_SUCCESS,
        REPOSITORY_RECOVERED_FAILURE = _REPOSITORY_RECOVERED_FAILURE,
        CLONE_REPOSITORY = _CLONE_REPOSITORY,
        CLONE_REPOSITORY_SUCCESS = _CLONE_REPOSITORY_SUCCESS,
        CLONE_REPOSITORY_FAILURE = _CLONE_REPOSITORY_FAILURE,
        CHECKOUT_REPOSITORY = _CHECKOUT_REPOSITORY,
        CHECKOUT_REPOSITORY_SUCCESS = _CHECKOUT_REPOSITORY_SUCCESS,
        CHECKOUT_REPOSITORY_FAILURE = _CHECKOUT_REPOSITORY_FAILURE,
        CHECK_ISMAS_TRIGGER = _CHECK_ISMAS_TRIGGER,
        CHECK_ISMAS_TRIGGER_WRONG_VALUE = _CHECK_ISMAS_TRIGGER_WRONG_VALUE,
        CHECK_ISMAS_TRIGGER_SUCCESS = _CHECK_ISMAS_TRIGGER_SUCCESS,
        CHECK_ISMAS_TRIGGER_FAILURE = _CHECK_ISMAS_TRIGGER_FAILURE,
        INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER = _INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER,
        INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER = _INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER,
        PULL_NEW_BRANCH = _PULL_NEW_BRANCH,
        PULL_NEW_BRANCH_FAILURE = _PULL_NEW_BRANCH_FAILURE,
        PULL_NEW_BRANCH_SUCCESS = _PULL_NEW_BRANCH_SUCCESS,
        CHECKOUT_BRANCH = _CHECKOUT_BRANCH,
        CHECKOUT_BRANCH_SUCCESS = _CHECKOUT_BRANCH_SUCCESS,
        CHECKOUT_BRANCH_FAILURE = _CHECKOUT_BRANCH_FAILURE,
        UPDATE_REPOSITORY = _UPDATE_REPOSITORY,
        UPDATE_REPOSITORY_SUCCESS = _UPDATE_REPOSITORY_SUCCESS,
        UPDATE_REPOSITORY_FAILURE = _UPDATE_REPOSITORY_FAILURE,
        CHECK_FOR_REPOSITORY_CHANGES = _CHECK_FOR_REPOSITORY_CHANGES,
        CHECK_FOR_REPOSITORY_CHANGES_SUCCESS = _CHECK_FOR_REPOSITORY_CHANGES_SUCCESS,
        CHECK_FOR_REPOSITORY_CHANGES_FAILURE = _CHECK_FOR_REPOSITORY_CHANGES_FAILURE,
        FILES_TO_UPDATE = _FILES_TO_UPDATE,
        DOWNLOAD_FILES_TO_PSA_HARDWARE = _DOWNLOAD_FILES_TO_PSA_HARDWARE,
        FILES_TO_DOWNLOAD = _FILES_TO_DOWNLOAD,
        EXEC_OPKG_COMMANDS = _EXEC_OPKG_COMMANDS,
        EXEC_OPKG_COMMAND_1 = _EXEC_OPKG_COMMAND_1,
        EXEC_OPKG_COMMAND_2 = _EXEC_OPKG_COMMAND_2,
        EXEC_OPKG_COMMAND_3 = _EXEC_OPKG_COMMAND_3,
        EXEC_OPKG_COMMAND_4 = _EXEC_OPKG_COMMAND_4,
        EXEC_OPKG_COMMAND_5 = _EXEC_OPKG_COMMAND_5,
        EXEC_OPKG_COMMAND_6 = _EXEC_OPKG_COMMAND_6,
        EXEC_OPKG_COMMAND_7 = _EXEC_OPKG_COMMAND_7,
        EXEC_OPKG_COMMAND_8 = _EXEC_OPKG_COMMAND_8,
        EXEC_OPKG_COMMAND_9 = _EXEC_OPKG_COMMAND_9,
        EXEC_OPKG_COMMAND_LAST = _EXEC_OPKG_COMMAND_LAST,
        EXEC_OPKG_COMMAND_SUCCESS = _EXEC_OPKG_COMMAND_SUCCESS,
        EXEC_OPKG_COMMAND_FAILURE = _EXEC_OPKG_COMMAND_FAILURE,
        DOWNLOAD_CONFIG_FILE = _DOWNLOAD_CONFIG_FILE,
        DOWNLOAD_CONFIG_FILE_SUCCESS = _DOWNLOAD_CONFIG_FILE_SUCCESS,
        DOWNLOAD_CONFIG_FILE_FAILURE = _DOWNLOAD_CONFIG_FILE_FAILURE,
        DOWNLOAD_CASH_FILE = _DOWNLOAD_CASH_FILE,
        DOWNLOAD_CASH_FILE_FAILURE = _DOWNLOAD_CASH_FILE_FAILURE,
        DOWNLOAD_CASH_FILE_SUCCESS = _DOWNLOAD_CASH_FILE_SUCCESS,
        DOWNLOAD_DEVICE_FILE = _DOWNLOAD_DEVICE_FILE,
        DOWNLOAD_DEVICE_FILE_FAILURE = _DOWNLOAD_DEVICE_FILE_FAILURE,
        DOWNLOAD_DEVICE_FILE_SUCCESS = _DOWNLOAD_DEVICE_FILE_SUCCESS,
        DOWNLOAD_JSON_FILE = _DOWNLOAD_JSON_FILE,
        DOWNLOAD_JSON_FILE_FAILURE = _DOWNLOAD_JSON_FILE_FAILURE,
        DOWNLOAD_JSON_FILE_SUCCESS = _DOWNLOAD_JSON_FILE_SUCCESS,
        DOWNLOAD_DEVICE_CONTROLLER = _DOWNLOAD_DEVICE_CONTROLLER,
        DOWNLOAD_DEVICE_CONTROLLER_SUCCESS = _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS,
        DOWNLOAD_DEVICE_CONTROLLER_FAILURE = _DOWNLOAD_DEVICE_CONTROLLER_FAILURE,
        DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS = _DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS,
        DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE = _DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE,
        SYNC_CUSTOMER_REPOSITORY = _SYNC_CUSTOMER_REPOSITORY,
        SYNC_CUSTOMER_REPOSITORY_SUCCESS = _SYNC_CUSTOMER_REPOSITORY_SUCCESS,
        SYNC_CUSTOMER_REPOSITORY_FAILURE = _SYNC_CUSTOMER_REPOSITORY_FAILURE,
        SAVE_LOGS = _SAVE_LOGS,
        SAVE_LOGS_SUCCESS = _SAVE_LOGS_SUCCESS,
        SAVE_LOGS_FAILURE = _SAVE_LOGS_FAILURE,
        SEND_LAST_VERSION = _SEND_LAST_VERSION,
        UPDATE_FINALIZE = _UPDATE_FINALIZE,
        UPDATE_SUCCEEDED = _UPDATE_SUCCEEDED,
        UPDATE_ACTIVATED = _UPDATE_ACTIVATED,
        UPDATE_NOT_NECESSARY = _UPDATE_NOT_NECESSARY,
        UPDATE_FAILED = _UPDATE_FAILED,
        FINISHED = _FINISHED,
        DEBUG = _DEBUG,
        ERROR = _ERROR,
        NONE = _NONE
    };

private:
    QStringList m_debugMsg;
    QStringList m_guiMsg;
    QStringList m_ismasMsg;
    UPDATE_STEP m_currentStep;
    static Worker *instance;
    QStringList m_opkgCommands;
    Update *m_update = nullptr;
    hwinf *m_hw = nullptr;
    UPDATE_STEP m_lastFailedUpdateStep = UPDATE_STEP::NONE;

protected:
    virtual void run();

public:
    QDebug CONSOLE(QStringList const &lst = QStringList()) {
        m_debugMsg = lst;
        return QDebug(QtMsgType::QtInfoMsg);
    }

    IsmasClient &ISMAS(QStringList const &lst = QStringList()) {
        m_ismasMsg = lst;
        return m_ismasClient;
    }

    ApismClientForUpdate &clientForUpdate() { return m_clForUpdate; }
    ApismClientForUpdate const &clientForUpdate() const { return m_clForUpdate; }

    Worker *GUI(QStringList const &lst = QStringList()) {
        m_guiMsg = lst;
        return this;
    }

    static QMap<UPDATE_STEP, const char*> const &getSmap() {
        return smap;
    }

    static QString getATBUpdateToolYoctoVersion();
    static QString getATBUpdateToolYoctoInstallationStatus();
    static QString getAPISMYoctoVersion();
    static QString getAPISMYoctoInstallationStatus();
    static QString getDCVersionPreparedForDownload(QString const &filename);

    static const QString UPDATE_STEP_OK;
    static const QString UPDATE_STEP_DONE;
    static const QString UPDATE_STEP_FAIL;
    static const QString UPDATE_STEP_WRONG;
    static const QString UPDATE_STEP_SUCCESS;

    explicit Worker(int customerNr, // 281
                    int machineNr,
                    int zoneNr,
                    QString repositoryUrl,
                    QString branchName,
                    QString pluginDir,
                    QString pluginName,
                    QString workingDir = ".",
                    bool noUpdatePsaHardware = false,
                    bool alwaysDownloadConfig = false,
                    bool alwaysDownloadDC = false,
                    bool dryRun = false,
                    QObject *parent = nullptr,
                    char const *serialInterface = SERIAL_PORT,
                    char const *baudrate = "115200");
    ~Worker();

    void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow; }
    void setProgress(int progress);
    void displayProgressInMainWindow(int progress);
    void startProgressLoop();
    void stopProgressLoop();
    void setHW(hwinf *hw) { m_hw = hw; }
    hwinf *getHW() { return m_hw; }

    QString customerRepository() { return m_customerRepository; }

    IsmasClient &getIsmasClient() { return m_ismasClient; }
    IsmasClient const &getIsmasClient() const { return m_ismasClient; }

    bool updateProcessRunning() const { return m_updateProcessRunning; }
    UPDATE_STEP currentStep() const { return m_currentStep; }

    int machineNr() const { return m_machineNr; }
    int customerNr() const { return m_customerNr; }
    int zoneNr() const { return m_zoneNr; }
    QString apismVersion() const { return m_apismVersion; }
    QString atbUpdateToolVersion() const { return m_atbUpdateToolVersion; }

    MainWindow *mainWindow() { return m_mainWindow; }
    MainWindow const *mainWindow() const { return m_mainWindow; }

    Update *update() { return m_update; }
    Update const *update() const { return m_update; }

    bool jsUpdate();
    bool dcUpdate();
    QDateTime start() { return m_start; }

    QByteArray standardOutput() const { return m_standardOutput; }

    WorkList const &workList() const { return m_workList; }
    WorkList &workList() { return m_workList; }

    QTimer *summaryTimer() { return &m_summaryTimer; }

signals:
    void appendText(QString, QString suffix = "");
    void insertText(QString);
    void replaceLast(QString, QString);
    void replaceLast(QStringList, QString);
    void showErrorMessage(QString title, QString description);
    void showStatusMessage(QString title, QString description);
    void showErrorMessage(QStringList titleAndDesc);
    void showStatusMessage(QStringList titleAndDesc);
    void stopStartTimer();
    void restartExitTimer();
    void enableExit();
    void disableExit();
    void showDcDownload(QString);
    void showJsonDownload(QString);
    void showTariffUpdate(QString);
    void showISMASChecks(QString);
    void showISMASConnectivity(QString);
    void showCustRepoStatus(QString);
    void showUpdateRequest(QString);
    void showExecOpkgStatus(QString);
    void showExecOpkgCommand(QString);
    void showExecOpkgOverallResult(QString,bool);
    void showDownloadDCJsonFilesStatus(QString);
    void showSyncCustRepoStatus(QString);
    void showUpdateDCFirmware(QString);
    void summary();
    void showSummary(QString);
    void setDcDownloadProgress(int);

private slots:
    bool updateTriggerSet();
    bool customerEnvironment();
    bool filesToUpdate();
    bool downloadFilesToPSAHardware();
    bool syncCustomerRepositoryAndFS();
    // bool sendIsmasLastVersionNotification(int progress);
    bool saveLogFile();

public slots:
    void readyReadStandardOutput();

private:
    PSAInstalled getPSAInstalled();
    static bool sendLastVersionOnce;
    void privateUpdate();
    bool computeFilesToDownload();
    bool execOpkgCommands();

    QDateTime m_start;
    QByteArray m_standardOutput;

    static const QMap<UPDATE_STEP, const char*> smap;

    // CONSOLE()
    friend UPDATE_STEP operator<<(QDebug debug, UPDATE_STEP step) {
        if (!Worker::instance) {
            return step;
        }

        Worker::instance->m_currentStep = step;
        QStringList lst = QStringList(smap[step]);

        switch (step) {
        case UPDATE_STEP::NONE: {
        } break;
        case UPDATE_STEP::STARTED: {
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("CURRENT TIME ...............%1").arg(QDateTime::currentDateTime().toString(Qt::ISODate))
                    << QString("OS VERSION .................%1").arg(instance->m_osVersion)
                    << QString("ATBQT VERSION ..............%1").arg(instance->m_atbqtVersion)
                    << QString("CPU SERIAL .................%1").arg(instance->m_cpuSerial)
                    << QString("CUSTOMER_NR ................%1").arg(instance->m_customerNr)
                    << QString("CUSTOMER_NR_STR ............%1").arg(instance->m_customerNrStr)
                    << QString("CUSTOMER_REPOSITORY_PATH ...%1").arg(instance->m_customerRepositoryPath)
                    << QString("CUSTOMER_REPOSITORY ........%1").arg(instance->m_customerRepository)
                    << QString("MACHINE_NR .................%1").arg(instance->m_machineNr)
                    << QString("ZONE_NR ....................%1").arg(instance->m_zoneNr)
                    << QString("BRANCH_NAME ................%1").arg(instance->m_branchName)
                    << QString("PLUGIN_NAME ................%1").arg(instance->m_pluginName)
                    << QString("WORKING_DIRECTORY ..........%1").arg(instance->m_workingDirectory)
                    << QString("APISM VERSION ..............%1").arg(instance->m_apismVersion)
                    << QString("ATB UPDATE TOOL VERSION ....%1").arg(instance->m_atbUpdateToolVersion));
        } break;
        case UPDATE_STEP::CHECK_REPOSITORY:
        break;
        case UPDATE_STEP::CHECK_SANITY:
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("CHECK SANITY OF CUSTOMER REPOSITORY %1")
                        .arg(instance->m_customerRepository));
        break;
        case UPDATE_STEP::CHECK_SANITY_SUCCESS:
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("SANITY OF CUSTOMER REPOSITORY %1 OK")
                        .arg(instance->m_customerRepository));
        break;
        case UPDATE_STEP::CHECK_SANITY_FAILURE:
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("CORRUPTED CUSTOMER REPOSITORY %1. REPAIRING...")
                        .arg(instance->m_customerRepository));
        break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS:
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("CORRUPTED CUSTOMER REPOSITORY %1. REPAIRING DONE")
                        .arg(instance->m_customerRepository));
        break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE:
            Utils::printUpdateStatusMsg(
                debug,
                QStringList(smap[step])
                    << QString("CORRUPTED CUSTOMER REPOSITORY %1. REPAIRING FAILED")
                        .arg(instance->m_customerRepository));
        break;
        case UPDATE_STEP::CHECK_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CLONE_REPOSITORY:
        break;
        case UPDATE_STEP::CLONE_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::CLONE_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY:
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER:
        break;
        case UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER:
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::PULL_NEW_BRANCH_FAILURE: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::PULL_NEW_BRANCH_SUCCESS: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::CHECKOUT_BRANCH:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH_FAILURE:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY:
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES:
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_FAILURE:
        break;
        case UPDATE_STEP::FILES_TO_UPDATE: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::FILES_TO_DOWNLOAD:
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMANDS:
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_1:
            __attribute__((fallthrough));
            // [[fallthrough]] -> c++17 -> unknown for clang
        case UPDATE_STEP::EXEC_OPKG_COMMAND_2:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_3:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_4:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_5:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_6:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_7:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_8:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_9:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_LAST:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS:
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE: {
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE:
        break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS:
        break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE:
        break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE:
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY:
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::SAVE_LOGS:
        break;
        case UPDATE_STEP::SAVE_LOGS_SUCCESS:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::SAVE_LOGS_FAILURE:
        break;
        case UPDATE_STEP::SEND_LAST_VERSION:
            // SEND_LAST_VERSION_CORRECTION
        break;
        case UPDATE_STEP::UPDATE_SUCCEEDED:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::UPDATE_ACTIVATED:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::UPDATE_NOT_NECESSARY:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::UPDATE_FAILED:
        break;
        case UPDATE_STEP::FINISHED:
            lst << instance->m_debugMsg;
            Utils::printUpdateStatusMsg(debug, lst);
        break;
        case UPDATE_STEP::DEBUG: {
            lst << instance->m_debugMsg;
            qCritical() << __LINE__ << lst;
            Utils::printUpdateStatusMsg(debug, lst);
        } break;
        case UPDATE_STEP::ERROR:
            //Utils::printUpdateStatusMsg(
            //    debug, QStringList(smap[step]) << instance->m_errorMsg);
        break;
        }

        instance->m_debugMsg.clear();

        return step;
    }

    // ISMAS()
    friend UPDATE_STEP operator<<(IsmasClient &ismasClient, UPDATE_STEP step) {

        if (!Worker::instance) {
            return step;
        }

        Worker::instance->m_currentStep = step;
        // QStringList lst = QStringList(smap[step]);

        switch (step) {
        case UPDATE_STEP::NONE: {
        } break;
        case UPDATE_STEP::STARTED: {
            ismasClient.setProgressInPercent(_STARTED);
        } break;
        case UPDATE_STEP::CHECK_REPOSITORY:
            ismasClient.setProgressInPercent(_CHECK_REPOSITORY);
        break;
        case UPDATE_STEP::CHECK_REPOSITORY_SUCCESS: {
            ismasClient.setProgressInPercent(_CHECK_REPOSITORY_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _CHECKOUT_REPOSITORY_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECK_REPOSITORY],
                        QString("REPOSITORY %1 AND BRANCH %2 OK")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_REPOSITORY_FAILURE: {
            ismasClient.setProgressInPercent(_CHECK_REPOSITORY_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _CHECKOUT_REPOSITORY_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_SWITCH_BRANCH_ERROR,
                        smap[UPDATE_STEP::CHECKOUT_REPOSITORY],
                        QString("REPOSITORY %1 and BRANCH %2 ***NOT OK***")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_SANITY: {
            ismasClient.setProgressInPercent(_CHECK_SANITY);
        } break;
        case UPDATE_STEP::CHECK_SANITY_SUCCESS: {
            ismasClient.setProgressInPercent(_CHECK_SANITY_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _CHECK_SANITY_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECK_SANITY],
                        QString("SANITY OF %1 (BRANCH %2) OK")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_SANITY_FAILURE: {
            ismasClient.setProgressInPercent(_CHECK_SANITY_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _CHECK_SANITY_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_CHECK_REPOSITORY_ERROR,
                        smap[UPDATE_STEP::CHECK_SANITY],
                        QString("SANITY OF %1 and BRANCH %2 ***NOT*** OK")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS: {
            ismasClient.setProgressInPercent(_REPOSITORY_RECOVERED_SUCCESS);
        } break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE: {
            ismasClient.setProgressInPercent(_REPOSITORY_RECOVERED_FAILURE);
        } break;
        case UPDATE_STEP::CLONE_REPOSITORY: {
            ismasClient.setProgressInPercent(_CLONE_REPOSITORY);
        } break;
        case UPDATE_STEP::CLONE_REPOSITORY_SUCCESS: {
            ismasClient.setProgressInPercent(_CLONE_REPOSITORY_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _CLONE_REPOSITORY_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CLONE_REPOSITORY],
                        QString("CLONED REPOSITORY %1 AND CHECKED OUT BRANCH %2")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
                                                   ismasUpdateNews);
        } break;
        case UPDATE_STEP::CLONE_REPOSITORY_FAILURE: {
            ismasClient.setProgressInPercent(_CLONE_REPOSITORY_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010 -> even on error: U0002/3 are sent only once
                        _CLONE_REPOSITORY_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_CLONE_ERROR,
                        smap[UPDATE_STEP::CHECKOUT_REPOSITORY],
                        QString("CLONING REPOSITORY %1 OR CHECKING OUT BRANCH %2 FAILED")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY:
            ismasClient.setProgressInPercent(_CHECKOUT_REPOSITORY);
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_SUCCESS: {
            ismasClient.setProgressInPercent(_CHECKOUT_REPOSITORY_SUCCESS);
            ismasClient.sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.cloneAndCheckoutCustomerRepository(
                          QString("CHECKED OUT REPOSITORY %1 AND CHECKED OUT BRANCH %2")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A"));
        } break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_FAILURE: {
            ismasClient.setProgressInPercent(_CHECKOUT_REPOSITORY_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010 -> even on error: U0002/3 are sent only once
                        _CHECKOUT_REPOSITORY_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_SWITCH_BRANCH_ERROR,
                        smap[UPDATE_STEP::CHECKOUT_REPOSITORY],
                        QString("%1: CHECKING OUT BRANCH %2 FAILED")
                            .arg(instance->m_customerRepository)
                            .arg(instance->m_gc.branchName()).toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER: {
            ismasClient.setProgressInPercent(_CHECK_ISMAS_TRIGGER);
        } break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS: {
            ismasClient.setProgressInPercent(_CHECK_ISMAS_TRIGGER_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, //
                        _CHECK_ISMAS_TRIGGER_SUCCESS,
                        (instance->m_updateNotNecessary)
                            ? IsmasClient::RESULT_CODE::NO_UPDATE_NECESSARY
                                : IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS],
                        instance->m_updateNotNecessary
                            ? QString("NO-UPDATE-NECESSARY (%1:%2)")
                                .arg(instance->m_customerRepository)
                                .arg(instance->m_gc.branchName()).toStdString().c_str()
                                : QString("ISMAS-TRIGGER ON WAIT").toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE: {
            ismasClient.setProgressInPercent(_CHECK_ISMAS_TRIGGER_WRONG_VALUE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_TEST_TRIGGER, // U0099
                        _CHECK_ISMAS_TRIGGER_WRONG_VALUE,
                        IsmasClient::RESULT_CODE::ISMAS_TRIGGER_ERROR,
                        smap[UPDATE_STEP::CHECK_ISMAS_TRIGGER],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE: {
            ismasClient.setProgressInPercent(_CHECK_ISMAS_TRIGGER_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_TEST_TRIGGER, // U0099
                        _CHECK_ISMAS_TRIGGER_FAILURE,
                        IsmasClient::RESULT_CODE::ISMAS_TRIGGER_ERROR,
                        smap[UPDATE_STEP::CHECK_ISMAS_TRIGGER],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                    ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER: {
            ismasClient.setProgressInPercent(_INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER: {
            ismasClient.setProgressInPercent(_INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::PULL_NEW_BRANCH: {
            ismasClient.setProgressInPercent(_PULL_NEW_BRANCH);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _PULL_NEW_BRANCH,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        }
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH_FAILURE: {
            ismasClient.setProgressInPercent(_PULL_NEW_BRANCH_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010 -> even on error: U0002/3 are sent only once
                        _PULL_NEW_BRANCH_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_PULL_ERROR,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        }
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH_SUCCESS: {
            ismasClient.setProgressInPercent(_PULL_NEW_BRANCH_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE, // U0010
                        _PULL_NEW_BRANCH_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        }
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH: {
            ismasClient.setProgressInPercent(_CHECKOUT_BRANCH);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        "U0010",
                        _CHECKOUT_BRANCH_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS: {
            ismasClient.setProgressInPercent(_CHECKOUT_BRANCH_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        "U0010",
                        _CHECKOUT_BRANCH_SUCCESS,
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::CHECKOUT_BRANCH_FAILURE: {
            ismasClient.setProgressInPercent(_CHECKOUT_BRANCH_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_FAILURE, // U0003
                        _CHECKOUT_BRANCH_FAILURE,
                        IsmasClient::RESULT_CODE::GIT_SWITCH_BRANCH_ERROR,
                        smap[UPDATE_STEP::CHECKOUT_BRANCH],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1
                            ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::UPDATE_REPOSITORY:
            ismasClient.setProgressInPercent(_UPDATE_REPOSITORY);
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS:
            ismasClient.setProgressInPercent(_UPDATE_REPOSITORY_SUCCESS);
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_FAILURE:
            ismasClient.setProgressInPercent(_UPDATE_REPOSITORY_FAILURE);
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES:
            ismasClient.setProgressInPercent(_CHECK_FOR_REPOSITORY_CHANGES);
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_SUCCESS:
            ismasClient.setProgressInPercent(_CHECK_FOR_REPOSITORY_CHANGES_SUCCESS);
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_FAILURE:
            ismasClient.setProgressInPercent(_CHECK_FOR_REPOSITORY_CHANGES_FAILURE);
        break;
        case UPDATE_STEP::FILES_TO_UPDATE:
            ismasClient.setProgressInPercent(_FILES_TO_UPDATE);
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::FILES_TO_DOWNLOAD: {
            ismasClient.setProgressInPercent(_FILES_TO_DOWNLOAD);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_JSON_FILE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::EXEC_OPKG_COMMANDS:
            ismasClient.setProgressInPercent(_EXEC_OPKG_COMMANDS);
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_1:
            ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_1);
            __attribute__((fallthrough)); // [[fallthrough]]; -> c++17, unknown to clang
        case UPDATE_STEP::EXEC_OPKG_COMMAND_2: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_2);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_3: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_3);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_4: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_4);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_5: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_5);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_6: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_5: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_6);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_7: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_5: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_6: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_7);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_8: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_5: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_6: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_7: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_8);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_9: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_5: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_6: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_7: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_8: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_9);
            } __attribute__((fallthrough));
        }
        case UPDATE_STEP::EXEC_OPKG_COMMAND_LAST: {
            switch(step) {
            case UPDATE_STEP::EXEC_OPKG_COMMAND_1: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_2: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_3: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_4: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_5: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_6: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_7: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_8: break;
            case UPDATE_STEP::EXEC_OPKG_COMMAND_9: break;
            default: ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_LAST);
            }
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[step],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS: {
            ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::EXEC_OPKG_COMMANDS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE: {
            ismasClient.setProgressInPercent(_EXEC_OPKG_COMMAND_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_FAILURE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::OPKG_COMMANDS_ERROR,
                        smap[step],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_CONFIG_FILE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_SUCCESS);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
                        smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_CASH_FILE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
                        smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE_SUCCESS);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
                        smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
            //ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE_SUCCESS);
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_JSON_FILE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE_FAILURE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
                        smap[UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
            ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
            ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_CONTROLLER);
        break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS: {
            ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_CONTROLLER_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE:
            ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_CONTROLLER_FAILURE);
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS: {
            ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE:
            ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE);
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY: {
            ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS: {
            ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE:
            ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY_FAILURE);
        break;
        case UPDATE_STEP::SAVE_LOGS:
            ismasClient.setProgressInPercent(_SAVE_LOGS);
        break;
        case UPDATE_STEP::SAVE_LOGS_SUCCESS: {
            ismasClient.setProgressInPercent(_SAVE_LOGS_SUCCESS);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_CONTINUE,
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[step],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::SAVE_LOGS_FAILURE:
            ismasClient.setProgressInPercent(_SAVE_LOGS_FAILURE);
        break;
        case UPDATE_STEP::SEND_LAST_VERSION: {
            if (Worker::sendLastVersionOnce == false) {
                ismasClient.setProgressInPercent(_SEND_LAST_VERSION + _SEND_LAST_VERSION_CORRECTION);
                ismasClient.sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
                    QString("#M=APISM#C=CMD_SENDVERSION#J=") +
                        ismasClient.updateOfPSASendVersion(instance->getPSAInstalled()));
                Worker::sendLastVersionOnce = true;
            }
        } break;
        case UPDATE_STEP::UPDATE_SUCCEEDED: {
            ismasClient.setProgressInPercent(_UPDATE_SUCCEEDED + _UPDATE_SUCCEEDED_CORRECTION);
            if (instance->m_automaticUpdate == false) {
                QString const &ismasUpdateNews =
                    QString("#M=APISM#C=CMD_EVENT#J=") +
                        ismasClient.updateNewsToIsmas(
                            _ISMAS_DONE, // WAIT-button set to 100%
                            ismasClient.getProgressInPercent(),
                            IsmasClient::RESULT_CODE::SUCCESS,
                            smap[UPDATE_STEP::UPDATE_FINALIZE],
                            instance->m_ismasMsg.join(' ').toStdString().c_str(),
                            instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
                ismasClient.sendRequestReceiveResponse(
                    IsmasClient::APISM::DB_PORT, ismasUpdateNews);
            }
        } break;
        case UPDATE_STEP::UPDATE_ACTIVATED: {
            ismasClient.setProgressInPercent(_UPDATE_ACTIVATED + _UPDATE_ACTIVATED_CORRECTION);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        (instance->m_automaticUpdate ? _ISMAS_NO_UPDATE_NECESSARY : _ISMAS_SET_WAIT_OK), // U0002 or M0100
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::SUCCESS,
                        smap[UPDATE_STEP::UPDATE_FINALIZE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::UPDATE_NOT_NECESSARY: {
            ismasClient.setProgressInPercent(_UPDATE_NOT_NECESSARY + _UPDATE_NOT_NECESSARY_CORRECTION);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        (instance->m_automaticUpdate ? _ISMAS_NO_UPDATE_NECESSARY : _ISMAS_SET_WAIT_OK), // U0002 or M0100
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::NO_UPDATE_NECESSARY,
                        smap[UPDATE_STEP::UPDATE_FINALIZE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::UPDATE_FAILED: {
            ismasClient.setProgressInPercent(_UPDATE_FAILED);
            QString const &ismasUpdateNews =
                QString("#M=APISM#C=CMD_EVENT#J=") +
                    ismasClient.updateNewsToIsmas(
                        _ISMAS_FAILURE, // U0003 is sent only once
                        ismasClient.getProgressInPercent(),
                        IsmasClient::RESULT_CODE::UPDATE_IN_ERROR_STATE,
                        smap[UPDATE_STEP::UPDATE_FINALIZE],
                        instance->m_ismasMsg.join(' ').toStdString().c_str(),
                        instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
            ismasClient.sendRequestReceiveResponse(
                IsmasClient::APISM::DB_PORT, ismasUpdateNews);
        } break;
        case UPDATE_STEP::FINISHED:
            ismasClient.setProgressInPercent(_FINISHED);
        break;
        case UPDATE_STEP::DEBUG:
        break;
        case UPDATE_STEP::ERROR:
        break;
        }

        instance->m_ismasMsg.clear();

        return step;
    }

    // GUI()
    friend UPDATE_STEP operator<<(Worker *worker, UPDATE_STEP step) {
        if (!Worker::instance) {
            return step;
        }

        Worker::instance->m_currentStep = step;

        switch (step) {
        case UPDATE_STEP::NONE: {
        } break;
        case UPDATE_STEP::STARTED:
        break;
        case UPDATE_STEP::CHECK_REPOSITORY:
            emit worker->appendText("\nInitializing customer environment ...");
        break;
        case UPDATE_STEP::CHECK_SANITY:
        break;
        case UPDATE_STEP::CHECK_SANITY_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_SANITY_FAILURE:
        break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS:
        break;
        case UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE:
        break;
        case UPDATE_STEP::CHECK_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CLONE_REPOSITORY:
            emit worker->appendText("\nInitializing customer environment ...");
        break;
        case UPDATE_STEP::CLONE_REPOSITORY_SUCCESS:
            emit worker->replaceLast("Initializing customer environment",
                                     Worker::UPDATE_STEP_DONE);
        break;
        case UPDATE_STEP::CLONE_REPOSITORY_FAILURE:
            emit worker->replaceLast("Initializing customer environment",
                                     Worker::UPDATE_STEP_FAIL);
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY:
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_SUCCESS:
        break;
        case UPDATE_STEP::CHECKOUT_REPOSITORY_FAILURE:
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER:
            emit worker->appendText("\n" CHECK_UPDATE_TRIGGER_SET);
            if (worker->m_guiMsg.size() > 0) {
                emit worker->showStatusMessage(worker->m_guiMsg);
            }
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE:
            emit worker->replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_WRONG);
            emit worker->showErrorMessage(worker->m_guiMsg);
        break;
        case UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE:
            emit worker->replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
            emit worker->showErrorMessage(worker->m_guiMsg);
        break;
        case UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER:
        break;
        case UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER:
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH:
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH_FAILURE:
        break;
        case UPDATE_STEP::PULL_NEW_BRANCH_SUCCESS:
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH:
            emit worker->appendText("\nPrepare customer environment ...");
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS:
            emit worker->replaceLast("Prepare customer environment ...", UPDATE_STEP_DONE);
        break;
        case UPDATE_STEP::CHECKOUT_BRANCH_FAILURE:
            emit worker->replaceLast("Prepare customer environment ...", UPDATE_STEP_FAIL);
            emit worker->showErrorMessage(worker->m_guiMsg);
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY:
            emit worker->appendText("\nUpdate repository...");
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS:
            emit worker->replaceLast(QString("Update repository ..."), UPDATE_STEP_DONE);
        break;
        case UPDATE_STEP::UPDATE_REPOSITORY_FAILURE:
            emit worker->replaceLast(QString("Update repository ..."), UPDATE_STEP_FAIL);
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES:
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_SUCCESS:
        break;
        case UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_FAILURE:
        break;
        case UPDATE_STEP::FILES_TO_UPDATE: {

            qCritical() << "FILES_TO_UPDATE" << worker->m_filesToUpdate;

            int const size = worker->m_filesToUpdate.size();
            if (size > 1) {
                emit worker->appendText(QString("Found %1 files to update :").arg(size), UPDATE_STEP_DONE);
                for (int i = 0; i < size; ++i) {
                    emit worker->appendText(QString("\n ") + worker->m_filesToUpdate.at(i));
                }
            }
            if (size == 1) {
                emit worker->appendText("Found 1 file to update :", UPDATE_STEP_DONE);
                emit worker->appendText(QString("\n ") + worker->m_filesToUpdate.at(0));
            }
        } break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE:
        break;
        case UPDATE_STEP::FILES_TO_DOWNLOAD:
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMANDS:
            emit worker->appendText("\n( ) Update opkg pakets ...");
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_1:
            __attribute__((fallthrough));
            // [[fallthrough]] -> c++17 -> unknown for clang
        case UPDATE_STEP::EXEC_OPKG_COMMAND_2:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_3:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_4:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_5:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_6:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_7:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_8:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_9:
            __attribute__((fallthrough));
        case UPDATE_STEP::EXEC_OPKG_COMMAND_LAST:
        break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS: {
            QString prepend = QString("(") + QString("%1").arg(worker->m_displayIndex).rightJustified(3, ' ') + QString(")")
                                + QString(" Update opkg pakets ... ");
            worker->m_opkgCommands.prepend(prepend);
            emit worker->replaceLast(worker->m_opkgCommands, UPDATE_STEP_DONE);
        } break;
        case UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE: {
            emit worker->replaceLast(QString("(") + QString("%1").arg(worker->m_displayIndex).rightJustified(3, ' ') + QString(")")
                          + QString(" Update opkg pakets ... "), UPDATE_STEP_FAIL);
        } break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE:
        break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS:
        break;
        case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE:
        break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
        } break;
        case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
        } break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
        break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS:
        break;
        case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE:
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS:
        break;
        case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE:
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY:
            emit worker->appendText("\nSync customer environment with filesystem ...");
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS:
            emit worker->replaceLast(QString("Sync customer environment with filesystem ..."), UPDATE_STEP_DONE);
        break;
        case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE:
            emit worker->replaceLast(QString("Sync customer environment with filesystem ..."), UPDATE_STEP_FAIL);
        break;
        case UPDATE_STEP::SAVE_LOGS:
        break;
        case UPDATE_STEP::SAVE_LOGS_SUCCESS:
        break;
        case UPDATE_STEP::SAVE_LOGS_FAILURE:
        break;
        case UPDATE_STEP::SEND_LAST_VERSION:
            emit worker->appendText(QString("Send last version info "), UPDATE_STEP_DONE);
        break;
        case UPDATE_STEP::UPDATE_SUCCEEDED:
            emit worker->appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS);
        break;
        case UPDATE_STEP::UPDATE_ACTIVATED:
        break;
        case UPDATE_STEP::UPDATE_NOT_NECESSARY:
        break;
        case UPDATE_STEP::UPDATE_FAILED:
            emit worker->appendText(QString("UPDATE "), UPDATE_STEP_FAIL);
        break;
        case UPDATE_STEP::FINISHED:
        break;
        case UPDATE_STEP::DEBUG:
            emit worker->showStatusMessage(worker->m_guiMsg);
        break;
        case UPDATE_STEP::ERROR:
            emit worker->showErrorMessage(worker->m_guiMsg);
        break;
        }

        worker->m_guiMsg.clear();

        return step;
    }
};

#endif // WORKER_H_INCLUDED