#ifndef BASECONN_H
#define BASECONN_H

#include <QObject>
#include <QTcpSocket>
#include <QDataStream>
#include <QDateTime>
#include <QTimer>
#include <QEventLoop>
#include <QSemaphore>
#include <QThread>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <string.h>

#include "headers/appsettings.h"
#include "headers/speedtimer.h"

class BaseConn : public QObject
{
    Q_OBJECT

public:
    explicit BaseConn(QObject *parent = nullptr);

    // values for the socket connection
    int connection_progress;
    QString ip;
    qint16 port = 3563;
    int errors;
    int errors_until_disconnect = 4;

    // the current state
    QString state;
        // can be:
        //  - 'disconnected'
        //  - 'connecting'
        //  - 'connected'

    QVariant connections;

    QString latestReadReply;

    //---general status values---//


private:
    QDateTime *date;
        //to get the current time

    QTcpSocket *socket;
        //socket for communication with the extention

    QSemaphore remoteSessions;

    int nextConnectionId;

    struct waitingRequest {
        int id;
        QEventLoop * loop;
        QJsonObject reply;
    };

    QList<waitingRequest> waitingRequests;

signals:
    void stateChanged();
        //is emitted, when the connection state changes

    void progressChanged();
        //is emmited during the connection process when the progress changes

    void gotUnexpectedReply(QString reply);

    void connectionsChanged();

    void connectionSlotReleased();

    void nextRemoteActionChanged();

    void nextRemoteActionDelayProgChanged();

    void gotError(QString error);

public slots:

    Q_INVOKABLE bool connectToHost();
        //function to connect to the base station

    Q_INVOKABLE void closeConnection();

    void gotError(QAbstractSocket::SocketError err);

    Q_INVOKABLE QVariantMap sendCommand(int header, QJsonValue data = "");

    Q_INVOKABLE int writeRemoteSetting(QString key, QString value);

    Q_INVOKABLE bool refreshConnections();

    // functions for the qml adapter
    QString getIP() const;
    void setIP(const QString &ipAdress);

    QString getState() const;
    void setState(QString newState);

    int getProgress() const;

    QVariant getConnections();

private slots:
     void readyRead();
};
extern BaseConn * pGlobalBaseConn;

#endif // BASECONN_H
