#ifndef WORKER_H_INCLUDED
#define WORKER_H_INCLUDED

#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QFile>
#include <QJsonObject>
#include <QHash>

#include "worker_thread.h"
#include "update.h"
#include "git/git_client.h"
#include "ismas/ismas_client.h"
#include "apism/apism_client.h"

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


enum class UPDATE_STATUS : quint8 {
    ISMAS_EMULATE_DATA_AVAILABLE,
    ISMAS_UPDATE_REQUEST_PENDING,
    ISMAS_UPDATE_REQUEST_FAILURE,
    ISMAS_UPDATE_REQUEST_TIMEOUT,
    ISMAS_UPDATE_REQUEST_SUCCESS,
    GIT_CHECKOUT_BRANCH_REQUEST,
    GIT_CHECKOUT_BRANCH_REQUEST_FAILURE,
    GIT_CHECKOUT_BRANCH_NOT_EXISTS,
    GIT_CHECKOUT_BRANCH_CHECKOUT_ERROR,
    GIT_FETCH_UPDATES_REQUEST,
    GIT_FETCH_UPDATES_REQUEST_FAILURE,
    GIT_FETCH_UPDATES_REQUEST_SSUCCESS,
    EXEC_OPKG_COMMANDS_REQUEST,
    EXEC_OPKG_COMMANDS_FAILURE,
    EXEC_OPKG_COMMAND_FAILURE,
    EXEC_OPKG_COMMAND_SUCCESS,
    EXEC_OPKG_COMMANDS_SUCCESS,
    RSYNC_UPDATES,
    RSYNC_UPDATES_FAILURE,
    RSYNC_UPDATES_SUCESS,
    DEVICE_CONTROLLER_UPDATE,
    DEVICE_CONTROLLER_UPDATE_FAILURE,
    DEVICE_CONTROLLER_UPDATE_SUCCESS,
    JSON_UPDATE,
    JSON_UPDATE_FAILURE,
    JSON_UPDATE_SUCCESS,
    ISMAS_UPDATE_INFO_CONFIRM,
    ISMAS_UPDATE_INFO_CONFIRM_FAILURE,
    ISMAS_UPDATE_INFO_CONFIRM_SUCCESS,
    ISMAS_CURRENT_PSA_STATUS_CONFIRM,
    ISMAS_CURRENT_PSA_STATUS_CONFIRM_FAILURE,
    ISMAS_CURRENT_PSA_STATUS_CONFIRM_SUCCESS
};

#define ISMAS_UPDATE_REQUESTS   (6)

class hwinf;
class Worker : public QObject {
    Q_OBJECT

    WorkerThread m_workerThread;
    QTimer m_startUpdateProcess;
    Update *m_update;
    ApismClient m_apismClient;
    int const m_customerNr;
    QString const m_customerNrStr;
    int const m_machineNr;
    int const m_zoneNr;
    QString const m_workingDirectory;
    QString const m_branchName;
    QString const m_customerRepository;
    GitClient m_gc;
    bool m_maintenanceMode;
    QString const m_osVersion;
    int m_ismasUpdateRequests;
    QTimer m_waitForNewUpdates;
    IsmasClient m_ismasClient;

    UPDATE_STATUS m_updateStatus;
    QString m_statusDescription;


    void executeOpkgCommand(QString opkgCommand);
    QString getOsVersion() const;

public:
    explicit Worker(hwinf *hw,
                    int customerNr, // 281
                    int machineNr,
                    int zoneNr,
                    QString branchName,
                    QString workingDir = ".",
                    bool maintenanceMode = false,
                    bool dryRun = false,
                    QObject *parent = nullptr,
                    char const *serialInterface = SERIAL_PORT,
                    char const *baudrate = "115200");
    ~Worker();
    void quit() { return m_workerThread.quit(); }

    static int read1stLineOfFile(QString fileName);

signals:
    void handleChangedFiles(QStringList);
    void summarizeUpload(QStringList);
    void summarizeRepositoryStatus();
    void sendCmdSendVersionToIsmas();
    void finishUpdateProcess(bool changes);
    void terminateUpdateProcess();

public slots:
    void onIsmasResponseReceived(QJsonObject ismasResponse);

private slots:
    void askIsmasForNewData();
    void onSendCmdSendVersionToIsmas();
    void onSummarizeRepositoryStatus();
    void onFinishUpdateProcess(bool changes);
    void onTerminateUpdateProcess();
    void onSummarizeUpload(QStringList);
    void onHandleChangedFiles(QStringList);
};

//Q_DECLARE_METATYPE((QHash<QString, QString>))
//Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)

#endif // WORKER_H_INCLUDED
