#include "pushclient.h"

#include <QDataStream>
#include <QTcpSocket>
#include <QProcess>
#include <QUrl>
#include <QJsonDocument>
#include <QJsonArray>

class PushClientPrivate
{
public:
    PushClientPrivate(PushClient *parent) : q_ptr(parent) {}

    QDataStream in;
    QDataStream out;

    QTcpSocket *socket;
    QString buffer;
    QString uuid;
    QString host;
    int port;

    void exec(QString base64Json);
    void reset();

    PushClient *q_ptr;
    Q_DECLARE_PUBLIC(PushClient)
};

PushClient::PushClient(QString uuid, QString host, int port, QObject *parent) :
    QObject(parent), dd_ptr(new PushClientPrivate(this))
{
    Q_D(PushClient);
    d->socket = new QTcpSocket(this);
    d->uuid = uuid;
    d->host = host;
    d->port = port;
    d->reset();

//    d->socket->write("{cdde82fa-6719-47aa-90a7-62dad7f1d390}");

    connect(d->socket, &QIODevice::readyRead, this, [ = ]() {
        auto base64 = d->socket->readAll();
        d->buffer += base64;
        if (base64.endsWith("\n")) {
            d->exec(d->buffer);
            d->buffer = "";
        }
    });

    connect(d->socket, static_cast< void (QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),
    this, [ = ](QAbstractSocket::SocketError err) {
        qDebug() << err;
        d->socket->disconnectFromHost();
        d->socket->close();
    });
}

PushClient::~PushClient()
{

}

void PushClient::reset()
{
    Q_D(PushClient);
    d->reset();
}

void PushClientPrivate::exec(QString base64Json)
{
    auto json = QByteArray::fromBase64(base64Json.toLatin1());
    auto array = QJsonDocument::fromJson(json).array();
    QStringList args;

    for (auto v : array) {
        args.push_back(v.toString());
    }
//    qDebug() << args;
    QProcess p;
    p.setProgram(args.takeAt(0));
    p.setArguments(args);
    p.start();
    p.waitForFinished(30 * 1000);
    auto ret = QString::fromLocal8Bit(p.readAll()).toUtf8().toBase64() + "\n";
//    qDebug() << ret;
    socket->write(ret);
}

void PushClientPrivate::reset()
{
    if (socket->isOpen() && socket->isValid()) {
        return;
    }
    qDebug() << "reset connect";
    socket->disconnectFromHost();
    socket->connectToHost(host, quint16(port));
    socket->write(uuid.toLatin1());
}
