#include "apism_client.h"
//#include "support/VendingData.h"
//#include "support/PersistentData.h"
//#include "support/utils.h"
//#include "ATBHMIconfig.h"

#include <QDebug>
#include <QByteArray>
#include <QHostAddress>
#include <QString>
#include <QList>
#include <QListIterator>
#include <QScopedPointer>
#include <QUuid>
#include <QProcess>
#include <QRegularExpression>

// Q_DECLARE_METATYPE(QAbstractSocket::SocketError)

ApismClient::ApismClient(QObject *eventReceiver, ATBHMIconfig *config, PersistentData *persistentData, QObject *parent)
    : QObject(parent)
    , healthEventReceiver(eventReceiver)
    , m_config(config)
    , persistentData(persistentData)
    , lastError(0)
    , lastErrorDescription("")
    , currentRequestUid("")
    , currentRequest(ISMAS::REQUEST::NO_REQUEST)
{   
    this->apismTcpSendClient            = new ApismTcpClient("127.0.0.1", "7777", this);
    this->apismTcpRequestResponseClient = new ApismTcpClient("127.0.0.1", "7778", this);

    connect(apismTcpRequestResponseClient, &ApismTcpClient::receivedData,
            this, &ApismClient::onReceivedResponse);
    connect(apismTcpRequestResponseClient, &ApismTcpClient::responseTimeout,
            this, &ApismClient::onRequestResponseClientResponseTimeout);

    connect(apismTcpSendClient, &ApismTcpClient::responseTimeout,
            this, &ApismClient::onSendClientResponseTimeout);



    // not needed as APISM closes the socket after we send data, so readyRead()
    // might not even fire
    // connect(&m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));

    // defined for Qt >= 5.15, we have 5.12
    // qRegisterMetaType<QAbstractSocket::SocketError>();
    // connect(&m_socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
    //    this, SLOT(onSocketError(&QAbstractSocket::SocketError)));
}

ApismClient::~ApismClient() {
}





void ApismClient::restartApism()
{
    QProcess::startDetached("/bin/systemctl", {"restart", "apism"});
}




//void ApismClient::onReadyRead() {   // parse APISM response
//    QByteArray data = m_socket.readAll();
//    qCritical() << "APISM-RESPONSE = (" << endl << data << endl << ")";
//}

void ApismClient::sendTransaction(const VendingData *vendingData) {


#if 0
    QScopedPointer<ISMAS::TransferData> transferData(new ISMAS::TransferData());

    PAYMENT_VARIANTS::TYPE paymentType = vendingData->getParameter("PaymentType").value<PAYMENT_VARIANTS::TYPE>();


    //////////////////////      DEVICE    //////////////////////////////////
    bool deviceSet = false;
    //QJsonValue tariffId("TariffInfo");
    //transferData->device.insert("TARIFID", tariffId);
    //QJsonValue group("group");
    //transferData->device.insert("GROUP", group);
    //QJsonValue zone("zone");
    //transferData->device.insert("ZONE", zone);
    if (deviceSet) {
        transferData->insert("DEVICE", transferData->device);
    }


    //////////////////////      TRANSACTION    /////////////////////////////


    bool transactionSet = false;

    if (vendingData->hasParameter("TRANSACTION_STATE")) {
        QVariant tstate = vendingData->getParameter("TRANSACTION_STATE");
        if (tstate.isValid() && tstate.type() == QVariant::Int) {
            transferData->transaction.state = tstate.toInt();
            transferData->transaction.insert("STATE", transferData->transaction.state);
            transactionSet = true;
        }
    }
    if (vendingData->hasParameter("TRANSACTION_UID")) {
        QVariant tuid = vendingData->getParameter("TRANSACTION_UID");
        if (tuid.isValid() && tuid.type() == QVariant::String) {
            transferData->transaction.uid = tuid.toString();
            transferData->transaction.insert("UID", transferData->transaction.uid);
            this->persistentData->setLastTransactionUID(tuid.toString());
            transactionSet = true;
        }
    }
    if (vendingData->hasParameter("TRANSACTION_TIMESTAMP")) {
        QVariant tstamp = vendingData->getParameter("TRANSACTION_TIMESTAMP");
        if (tstamp.isValid() && tstamp.type() == QVariant::String) {
            transferData->transaction.timestamp = tstamp.toString();
            transferData->transaction.insert("TIMESTAMP", transferData->transaction.timestamp);
            transactionSet = true;
        }
    }
    if (vendingData->hasParameter("TRANSACTION_TICKET_SEQUENCE_NUMBER")) {
        QVariant tsn = vendingData->getParameter("TRANSACTION_TICKET_SEQUENCE_NUMBER");
        if (tsn.isValid() && tsn.type() == QVariant::Int) {
            transferData->transaction.seq_tick_number = tsn.toInt();
            transferData->transaction.insert("TICKETNU", transferData->transaction.seq_tick_number);
            transactionSet = true;
        }
    }
    if (vendingData->hasParameter("LICENSEPLATE")) {
        QVariant lp = vendingData->getParameter("LICENSEPLATE");
        transferData->transaction.userText = QJsonValue::fromVariant(lp);
        transferData->transaction.insert("USERTEXT", transferData->transaction.userText);
        transferData->transaction.userTextType = "license plate";
        transferData->transaction.insert("USERTEXTTYPE", transferData->transaction.userTextType);
        transactionSet = true;
    }

    if (transactionSet) {
        transferData->insert("TRANSACTION", transferData->transaction);
    }


    //////////////////////        ITEM    //////////////////////////////////
    bool itemSet = false;

    if (vendingData->hasParameter("PermitType")) {
        QVariant idVariant = vendingData->getParameter("PermitType");
        transferData->item.id = idVariant.toString();
        transferData->item.insert("ID", transferData->item.id);
        itemSet = true;
    }
    if (vendingData->hasParameter("Product")) {
        QVariant nameVariant = vendingData->getParameter("Product");
        transferData->item.name = nameVariant.toString();
        transferData->item.insert("NAME", transferData->item.name);
        itemSet = true;
    }
    if (vendingData->hasParameter("PRICE_INFO_GROSS")) {
        int priceUint = vendingData->getUintParameter("PRICE_INFO_GROSS");
        transferData->item.price = priceUint;
        transferData->item.insert("PRICE", transferData->item.price);
        itemSet = true;
    }
    if (vendingData->hasParameter("PERIOD_START")) {
        QVariant startTimeVariant = vendingData->getParameter("PERIOD_START");
        transferData->item.startTime = utils::getISODateTimeWithMsAndOffset(startTimeVariant);
        transferData->item.insert("STARTTIME", transferData->item.startTime);
        itemSet = true;
    }
    if (vendingData->hasParameter("PERIOD_END")) {
        QVariant endTimeVariant = vendingData->getParameter("PERIOD_END");
        transferData->item.endTime = utils::getISODateTimeWithMsAndOffset(endTimeVariant);
        transferData->item.insert("ENDTIME", transferData->item.endTime);
        itemSet = true;
    }
    if (vendingData->hasParameter("ITEM_PRINT_TEXT")) {
        QVariant textVariant = vendingData->getParameter("ITEM_PRINT_TEXT");
        transferData->item.printText = textVariant.toString();
        transferData->item.insert("PRINTTEXT", transferData->item.printText);
        itemSet = true;
    }

    // set static data:

    // currency
    if (itemSet) {
        transferData->item.currency = this->m_config->getPaymentCurrencyISOCode();
        transferData->item.insert("CURRENCY", transferData->item.currency);
    }

    if (itemSet) {
        transferData->insert("ITEM", transferData->item);
    }

    ////////////////////////////////////////////////////////////////////////


    //////////////////////        PAYMENT     //////////////////////////////
    bool paymentSet = false;

    ///////////////////////////  PAYMENT.CASH  /////////////////////////////
    if (paymentType == PAYMENT_VARIANTS::TYPE::CASH) {
        bool cashSet = false;

        if (vendingData->hasParameter("PaymentCashCoins")) {
            QVariant coins = vendingData->getParameter("PaymentCashCoins");
            transferData->payment.cash.coins = coins.toInt();
            transferData->payment.cash.insert("COINS", transferData->payment.cash.coins);
            cashSet = true;
        }
        if (vendingData->hasParameter("PaymentCashChange")) {
            QVariant change = vendingData->getParameter("PaymentCashChange");
            transferData->payment.cash.change = change.toInt();
            transferData->payment.cash.insert("CHANGE", transferData->payment.cash.change);
            cashSet = true;
        }
        if (vendingData->hasParameter("PaymentCashOverpaid")) {
            QVariant overpaid = vendingData->getParameter("PaymentCashOverpaid");
            transferData->payment.cash.overpaid = overpaid.toInt();
            transferData->payment.cash.insert("OVERPAID", transferData->payment.cash.overpaid);
            cashSet = true;
        }

        // currency
        if (cashSet) {
            transferData->payment.cash.currency = this->m_config->getPaymentCurrencyISOCode();
            transferData->payment.cash.insert("CURRENCY", transferData->payment.cash.currency);
        }

        if (cashSet) {
            transferData->payment.insert("CASH", transferData->payment.cash);
            paymentSet = true;
        }
    }

    ///////////////////////////  PAYMENT.CARD  /////////////////////////////
    if (paymentType == PAYMENT_VARIANTS::TYPE::CARD) {
        paymentSet = true;
        bool cardSet = true;


        transferData->payment.card.insert("CARDNU", "unknown");

        transferData->payment.card.insert("VALUE", transferData->item.price);

        transferData->payment.card.insert("CARDTYPE", "unknown");


        transferData->payment.card.currency = this->m_config->getPaymentCurrencyISOCode();
        transferData->payment.card.insert("CURRENCY",  transferData->payment.card.currency);

        // transferData->payment.card.insert("TERMINALID", tid);
        //transferData->payment.card.insert("TERMINALRESULT", tresult);

        if (cardSet) {
            transferData->payment.insert("CARD", transferData->payment.card);
            paymentSet = true;
        }
    }

    if (paymentSet) {
        transferData->insert("PAYMENT", transferData->payment);
    }

    ////////////////////////////////////////////////////////////////////////


    /////////////////////////////  RESULT  /////////////////////////////////
    bool resultSet = false;


    if (vendingData->hasParameter("RESULT_DELIVERY")) {
        QVariant delVariant = vendingData->getParameter("RESULT_DELIVERY");
        transferData->result.delivery = delVariant.toJsonValue();
        transferData->result.insert("DELIVERY", transferData->result.delivery);
        resultSet = true;
    }
    if (vendingData->hasParameter("RESULT_RESULT")) {
        QVariant resVariant = vendingData->getParameter("RESULT_RESULT");
        transferData->result.result = resVariant.toJsonValue();
        transferData->result.insert("RESULT", transferData->result.result);
        resultSet = true;
    }
    if (vendingData->hasParameter("RESULT_ERROR_CODE")) {
        QVariant ecVariant = vendingData->getParameter("RESULT_ERROR_CODE");
        transferData->result.errorCode = ecVariant.toJsonValue();
        transferData->result.insert("ERRORCODE", transferData->result.errorCode);
        resultSet = true;
    }
    if (vendingData->hasParameter("RESULT_ERROR_MESSAGE")) {
        QVariant emsgVariant = vendingData->getParameter("RESULT_ERROR_MESSAGE");
        transferData->result.errorMsg = emsgVariant.toJsonValue();
        transferData->result.insert("ERRORMSG", transferData->result.errorMsg);
        resultSet = true;
    }

    if (resultSet) {
        transferData->insert("RESULT", transferData->result);
    }

    ////////////////////////////////////////////////////////////////////////


    QJsonDocument jsonDoc(*transferData);
    QByteArray data = "#M=APISM#C=CMD_TRANSACTION#J=";
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpSendClient->sendData(data);
}


void ApismClient::sendAccount(const QHash<QString, QVariant> & accountDataHash)
{
    QScopedPointer<ISMAS::AccountData> accountData(new ISMAS::AccountData());

    accountData->coinBox.UID = QUuid::createUuid().toString(QUuid::WithoutBraces);  // .mid(0, 8)
    accountData->insert("UID", accountData->coinBox.UID);

    accountData->coinBox.ChangeNumber = QJsonValue(static_cast<qint32>(this->persistentData->getNewCoinboxChangeNumber()));
    accountData->insert("COINBOX_CHANGE_NUMBER", accountData->coinBox.ChangeNumber);

    accountData->coinBox.Process = "COINBOX_CHANGE";
    accountData->insert("PROCESS",   accountData->coinBox.Process);

    accountData->insert("StartTime", utils::getISODateTimeWithMsAndOffset(persistentData->getAccountStartTime()));
    accountData->insert("EndTime",   utils::getCurrentISODateTimeWithMsAndOffset());
    accountData->insert("StartHash", persistentData->getFirstTransactionUID());
    accountData->insert("EndHash",   persistentData->getLastTransactionUID());

    // coins
    int numberOfCoinVariants = accountDataHash["NumberOfCoinVariants"].toInt();
    for (int i=0; i < numberOfCoinVariants;++i) {
        accountData->coinBox.coin.value         = accountDataHash["COIN_" + QString::number(i) + "_Value"].toInt();
        accountData->coinBox.coin.numberOfCoins = accountDataHash["COIN_" + QString::number(i) + "_Quantity"].toInt();
        accountData->coinBox.coin.insert("VALUE",    accountData->coinBox.coin.value);
        accountData->coinBox.coin.insert("QUANTITY", accountData->coinBox.coin.numberOfCoins);

        if (accountDataHash.contains("COIN_" + QString::number(i) + "_Currency")) {
            accountData->coinBox.coin.currency = accountDataHash["COIN_" + QString::number(i) + "_Currency"].toString();
            accountData->coinBox.coin.insert("CURRENCY", accountData->coinBox.coin.numberOfCoins);
        }

        accountData->insert("COIN_" + QString::number(i), accountData->coinBox.coin);
    }

    QJsonDocument jsonDoc(*accountData);
    QByteArray data = "#M=APISM#C=CMD_CashboxChange#J=";
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpSendClient->sendData(data);

    this->persistentData->clearForNewAccount();

    persistentData->serializeToFile();
}



void ApismClient::sendEvent(const ATBMachineEvent* machineEvent)
{
    QScopedPointer<ISMAS::EventData> eventData(new ISMAS::EventData());

    eventData->machineEvent.eventID = machineEvent->eventId;
    eventData->insert("EVENT_ID", eventData->machineEvent.eventID);

    eventData->machineEvent.deviceName = machineEvent->deviceName;
    eventData->insert("DeviceName", eventData->machineEvent.deviceName);

    eventData->machineEvent.reason = ATBMachineEvent::getEventClassString(machineEvent->machineEventClass);
    eventData->insert("Reason", eventData->machineEvent.reason);

    eventData->machineEvent.event = machineEvent->eventName;
    eventData->insert("Event", eventData->machineEvent.event);

    eventData->machineEvent.eventState = machineEvent->eventState;
    eventData->insert("EventState", eventData->machineEvent.eventState);

    eventData->machineEvent.timeStamp = machineEvent->timestamString;
    eventData->insert("Timestamp", eventData->machineEvent.timeStamp);

    eventData->machineEvent.parameter = machineEvent->parameterString;
    eventData->insert("Parameter", eventData->machineEvent.parameter);

    eventData->machineEvent.secondLevelInfo = machineEvent->secondLevelInfoString;
    eventData->insert("SecondLevelInfo", eventData->machineEvent.secondLevelInfo);


    QJsonDocument jsonDoc(*eventData);
    QByteArray data = "#M=APISM#C=CMD_EVENT#J=";
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpSendClient->sendData(data);

#endif

}


void ApismClient::sendState(const QString & state, const QString & msg)
{
    qCritical() << "ApismClient::sendState(): ";
    qCritical() << "            state: " << state;
    qCritical() << "              msg: " << msg;


    QJsonParseError parseError;
    QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
    if (parseError.error != QJsonParseError::NoError) {
        qCritical() << "ApismClient::sendState() invalid json msg: Parsing failed:" << parseError.error << parseError.errorString();
        return;
    }

    if (!document.isObject()) {
        qCritical() << "File is not JSON object!";
        return;
    }


    QScopedPointer<ISMAS::StateData> stateData(new ISMAS::StateData());

    QJsonObject stateObject = document.object();

    QJsonArray statesArray;
    statesArray.append(stateObject);

    // stateData->insert("TIMESTAMP", utils::getCurrentISODateTimeWithMsAndOffset());
    // stateData->insert("HW_States", statesArray);


    QJsonDocument jsonDoc(*stateData);
    QByteArray data = "#M=APISM#C=CMD_HW_STATUS#J=";
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpSendClient->sendData(data);
}







void ApismClient::sendMininformStartRequest(const VendingData* vendingData)
{
    this->currentRequest = ISMAS::REQUEST::START;

    struct MininFormTransferData : public QJsonObject {
        struct : public QJsonObject {
                    QJsonValue uid;                // MUST: uuid -> vendorId
                    QJsonValue posid;              //       terminal-id
                    QJsonValue authCode;           //       approval-code
                    QJsonValue stan;               // MUST
                    QJsonValue lpn;
                    QJsonValue transactionTime;     // MUST: Zeitstempel Verkauf
                    QJsonValue parkingStartTime;    // MUST: Startzeit
                    QJsonValue preAuthAmount;
                    QJsonValue hourlyRate;
                    QJsonValue vehicleCategory;
                    QJsonValue langCode;
                    QJsonValue zoneCode;
                } startAction;
    };

    QScopedPointer<MininFormTransferData> transferData(new MininFormTransferData());

#if 0
    transferData->startAction.uid = vendingData->getParameter("START_UID").toJsonValue();
    this->currentRequestUid = vendingData->getParameter("START_UID").toString();
    transferData->startAction.insert("UID", transferData->startAction.uid);

    transferData->startAction.insert("POSID", vendingData->getParameter("START_POSID").toString());

    transferData->startAction.insert("AUTHCODE", vendingData->getParameter("START_AuthCode").toString());

    transferData->startAction.insert("STAN", vendingData->getParameter("START_STAN").toString());

    transferData->startAction.insert("LPN", vendingData->getParameter("LICENSEPLATE").toString());

    transferData->startAction.insert("TRANSACTIONTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("START_TRANSACTIONTIME").toString()));

    transferData->startAction.insert("STARTTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("START_STARTTIME").toString()));

    transferData->startAction.insert("AMOUNT", static_cast<int>(vendingData->getUintParameter("PRICE_INFO_GROSS")));

    transferData->startAction.insert("RATE_H", static_cast<int>(vendingData->getUintParameter("PRICE_INFO_RATE_H")));

    transferData->startAction.insert("VEHICLETYPE", "01");  // Fixed value

    transferData->startAction.insert("LANGUAGE", "HUN");    // Fixed value

    transferData->startAction.insert("ZONE", vendingData->getParameter("MININFORM_ZONE").toString());

    transferData->insert("STARTACTION", transferData->startAction);

    QJsonDocument jsonDoc(*transferData);
    QByteArray data = "#M=APISM#C=REQ_START#J="; // REQ_... -> use port 7778
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpRequestResponseClient->sendData(data);
}

void ApismClient::sendMininformStopRequest(const VendingData* vendingData)
{
    this->currentRequest = ISMAS::REQUEST::STOP;

    struct MininFormTransferData : public QJsonObject {
        struct : public QJsonObject {
                  QJsonObject uid;                // MUST: uuid
                  QJsonObject posid;              //       terminal-id
                  QJsonObject stan;                // MUST
                  QJsonObject lpn;                 // MUST
                  QJsonObject stopTime;            // MUST: Stop-Zeit
                  QJsonObject langCode;
                  QJsonObject deviceId;
              } stopAction;
    };

    QScopedPointer<MininFormTransferData> transferData(new MininFormTransferData());

    this->currentRequestUid = QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 8);
    transferData->stopAction.insert("UID", this->currentRequestUid);

    transferData->stopAction.insert("POSID", vendingData->getParameter("STOP_POSID").toString());

    transferData->stopAction.insert("STAN", vendingData->getParameter("STOP_STAN").toString());

    transferData->stopAction.insert("LPN", vendingData->getParameter("LICENSEPLATE").toString());

    transferData->stopAction.insert("STOPTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("STOP_STOPTIME")));

    transferData->stopAction.insert("LANGUAGE", "HUN");    // Fixed value

    transferData->stopAction.insert("DEVICE_ID", this->m_config->getMachineNr());

    transferData->insert("STOPACTION", transferData->stopAction);

    QJsonDocument jsonDoc(*transferData);
    QByteArray data = "#M=APISM#C=REQ_STOP#J=";   // REQ_ -> use port 7778
    data += jsonDoc.toJson(QJsonDocument::Compact);

    this->apismTcpRequestResponseClient->sendData(data);
#endif
}


void ApismClient::sendSelfTest()
{
    this->currentRequest = ISMAS::REQUEST::SELF;

    QByteArray data = "#M=APISM#C=REQ_SELF#J={}";

    this->apismTcpRequestResponseClient->sendData(data);
}

void ApismClient::sendMininformPingRequest()
{
    this->currentRequest = ISMAS::REQUEST::PING;

    QByteArray data = "#M=APISM#C=REQ_Ping#J={\"281\":\"PING\"}";

    this->apismTcpRequestResponseClient->sendData(data);
}



void ApismClient::onReceivedResponse(QByteArray response)
{
    // get the root object
    QJsonParseError jsonParseError;
    QJsonDocument responseDoc = QJsonDocument::fromJson(response, &jsonParseError);

    if (jsonParseError.error != QJsonParseError::NoError) {
        qCritical() << "ApismClient::onReceivedResponse() response is no json data:";
        qCritical() << "     Error: " << jsonParseError.errorString();
        this->handleISMASResponseError();
        return;
    }

    QJsonObject rootObject = responseDoc.object();

    QStringList rootObjectKeys = rootObject.keys();

    // DEBUG
    qCritical() << "ApismClient::onReceivedResponse(): objects: " << rootObjectKeys;
    // results to:
    //  ApismClient::onReceivedResponse(): objects:  ("REQ_START#60044_Response", "Response")


    if(rootObjectKeys.indexOf(QRegularExpression("^REQ_START.*")) >= 0) {
        this->private_handleMininformStartResponse(rootObject["Response"].toObject());
    }
    else
    if(rootObjectKeys.indexOf(QRegularExpression("^REQ_STOP.*")) >= 0) {
        this->private_handleMininformStopResponse(rootObject["Response"].toObject());
    }
    else
    if(rootObjectKeys.indexOf(QRegularExpression("^REQ_SELF.*")) >= 0) {
        this->private_handleReqSelfResponse(rootObject["Response"].toObject());
    }
    else
    if(rootObjectKeys.indexOf(QRegularExpression("^REQ_PING.*")) >= 0) {
        this->private_handleReqPingResponse(rootObject["PING"].toObject());
    }
    else {
        qCritical() << "ApismClient::onReceivedResponse() for unknown Request: ";
        qCritical() << "                     currentRequestName: " << currentRequest;
        qCritical() << "                      rootObject.keys(): " << rootObjectKeys;
        this->handleISMASResponseError();
        return;
    }

    this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
}

void ApismClient::handleISMASResponseError()
{
    switch (this->currentRequest) {
    case ISMAS::REQUEST::NO_REQUEST:
        qCritical() << "ApismClient::onReceivedResponse() for unknown Request: " << currentRequest;
        break;
    case ISMAS::REQUEST::START:
        emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
        break;
    case ISMAS::REQUEST::STOP:
        emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
        break;
    case ISMAS::REQUEST::PING:
        emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
        break;
    case ISMAS::REQUEST::SELF:
        emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
        break;
    }
    this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
}

/*
{\r\n    \"REQ_START#53365_Response\": {\r\n        \"Aknoledge\": \"OK\"\r\n    },
 \r\n    \"Response\": {\r\n        \"Result\": \"ERR:Ung�ltiger Datums-String: \"\r\n    }\r\n}
*/

/*
: ISMAS received:  "{\r\n    \"REQ_PING#30844_Response\": {\r\n        \"Aknoledge\": \"OK\"\r\n    },
     "PING": { "IsAviable": "TRUE" }
  }"
*/

void ApismClient::onSendClientResponseTimeout()
{

}

void ApismClient::onRequestResponseClientResponseTimeout()
{
    switch (this->currentRequest) {
    case ISMAS::REQUEST::NO_REQUEST:
        qCritical() << "ApismClient::onRequestResponseClientResponseTimeout() for unknown Request: " << currentRequest;
        break;
    case ISMAS::REQUEST::START:
        emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
        break;
    case ISMAS::REQUEST::STOP:
        emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
        break;
    case ISMAS::REQUEST::PING:
        emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
        break;
    case ISMAS::REQUEST::SELF:
        emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
        break;
    }

    this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
}


void ApismClient::private_handleMininformStartResponse(QJsonObject response)
{
    emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
}

void ApismClient::private_handleMininformStopResponse(QJsonObject response)
{
    emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
}

void ApismClient::private_handleReqSelfResponse(QJsonObject response)
{
    emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
}

void ApismClient::private_handleReqPingResponse(QJsonObject response)
{
    emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
}




/************************************************************************************************
 * operators
 */
QDebug operator<< (QDebug debug, ISMAS::REQUEST request)
{
    switch(request) {
    case ISMAS::REQUEST::NO_REQUEST:
        debug << QString("ISMAS::REQUEST::NO_REQUEST");
        break;
    case ISMAS::REQUEST::START:
        debug << QString("ISMAS::REQUEST::START");
        break;
    case ISMAS::REQUEST::STOP:
        debug << QString("ISMAS::REQUEST::STOP");
        break;
    case ISMAS::REQUEST::PING:
        debug << QString("ISMAS::REQUEST::PING");
        break;
    case ISMAS::REQUEST::SELF:
        debug << QString("ISMAS::REQUEST::SELF");
        break;
    }
    return debug;
}

QString& operator<< (QString& str, ISMAS::REQUEST request)
{
    switch(request) {
    case ISMAS::REQUEST::NO_REQUEST:
        str = QString("ISMAS::REQUEST::NO_REQUEST");
        break;
    case ISMAS::REQUEST::START:
        str = QString("ISMAS::REQUEST::START");
        break;
    case ISMAS::REQUEST::STOP:
        str = QString("ISMAS::REQUEST::STOP");
        break;
    case ISMAS::REQUEST::PING:
        str = QString("ISMAS::REQUEST::PING");
        break;
    case ISMAS::REQUEST::SELF:
        str = QString("ISMAS::REQUEST::SELF");
        break;
    }
    return str;
}

