#ifndef APISM_CLIENT_H_INCLUDED
#define APISM_CLIENT_H_INCLUDED


#include "ismas_data.h"
#include "apism_tcp_client.h"

#include <QObject>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonParseError>
#include <QJsonValue>




QDebug operator<<(QDebug debug, ISMAS::REQUEST request);
QString& operator<<(QString& str, ISMAS::REQUEST request);

namespace nsApismInterface {

    enum class RESULT_STATE : quint8 {
        SUCCESS = 1,
        ERROR_BACKEND = 2,   // error from backand (e.g. backend replies with error)
        ERROR_NETWORK = 3,   // error from network (e.g. host not available)
        ERROR_TIMEOUT = 4,   // the operation timed out
        ERROR_PROCESS = 5,   // internal plugin error (e.g. bug in implementation)
        ERROR_RETRY = 6,     // retry operation
        INFO = 7
    };

}


class VendingData;
class ATBHMIconfig;
class PersistentData;
class ATBMachineEvent;
class ApismClient : public QObject {
    Q_OBJECT

public:
    explicit ApismClient(QObject *eventReceiver, ATBHMIconfig *config, PersistentData *persistentData, QObject *parent = 0);
    ~ApismClient();

    quint32 getLastError();
    const QString & getLastErrorDescription();

public slots:
    void sendSelfTest();
    void sendTransaction(const VendingData* vendingData);
    // void sendAccount(const QHash<QString, QVariant> &accountDataHash);
    //void sendEvent(const ATBMachineEvent* machineEvent);

    void sendState(const QString & state, const QString & msg);
    void sendUpdateInfoToIsmas(QString const &msg);
    void sendCmdSendVersionToIsmas(QString const &msg);
    void requestAvailableIsmasUpdates();


    //void sendMininformStartRequest(const VendingData* vendingData);
    //void sendMininformStopRequest(const VendingData* vendingData);
    //void sendMininformPingRequest();

    void restartApism();

signals:
    // public signals:
    void sendTransactionRespones(nsApismInterface::RESULT_STATE result);
    void sendAccountResponse(nsApismInterface::RESULT_STATE result);


    void sendMininformStartResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
    void sendMininformStopResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
    void sendMininformPingResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
    void sendReqSelfResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);

    void ismasResponseAvailable(QJsonObject ismasResponse);


private slots:
    // void onSocketError(QAbstractSocket::SocketError socketError);

    void onReceivedResponse(QByteArray response);

    void onSendClientResponseTimeout();
    void onRequestResponseClientResponseTimeout();

private:
    QObject *healthEventReceiver;
    ATBHMIconfig *m_config;

    PersistentData *persistentData;

    ApismTcpClient* apismTcpSendClient;
    ApismTcpClient* apismTcpRequestResponseClient;

    quint32 lastError;
    QString lastErrorDescription;

    QString currentRequestUid;
    ISMAS::REQUEST currentRequest;


    void private_handleMininformStartResponse(QJsonObject response);
    void private_handleMininformStopResponse(QJsonObject response);
    void private_handlePingResponse(QJsonObject response);
    void private_handleReqSelfResponse(QJsonObject response);
    void private_handleReqPingResponse(QJsonObject response);
    void private_handleIsmasParameterResponse(QJsonObject response);

    void handleISMASResponseError();

};

// Q_DECLARE_METATYPE(QAbstractSocket::SocketError)

#endif // APISM_CLIENT_H_INCLUDED
