#include "ThreadSocket.h"
#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
#include "preDefine.h"
#include "QsLog.h"

ThreadSocket::ThreadSocket(QObject *parent) : QObject(parent)
{
    _stopFlag = false;
    _stoped = false;
}


ThreadSocket::~ThreadSocket()
{
    QLOG_INFO() << "ThreadSocket::~ThreadSocket()......";
    emit threadClose();

    if(this->thread() != QThread::currentThread())
    {
        this->thread()->wait(20);
        QLOG_INFO() << "~ThreadSocket():: this->thread() != QThread::currentThread() ";
    } else {
        _thread->terminate();
    }
}

void ThreadSocket::moveToThread(QThread *thread, bool with_thread_start)
{
    _thread = thread;

    if(with_thread_start) {
        connect(thread, &QThread::started, this, &ThreadSocket::threadStart);
        connect(this, &ThreadSocket::threadClose, thread, &QThread::quit);
    }

    QObject::moveToThread(thread);

    if(with_thread_start ) {
        thread->start();
    }

}

bool ThreadSocket::S_PostRequest(const QJsonObject &requestJson, QJsonObject &recvJson, QString url, QString &error, QByteArray contentype)
{
    QNetworkAccessManager m_networkManger;

    if(QNetworkAccessManager::Accessible != m_networkManger.networkAccessible())
    {
        m_networkManger.setNetworkAccessible(QNetworkAccessManager::Accessible);
    }

    QNetworkRequest networkRequest;
    networkRequest.setUrl(url);
    networkRequest.setRawHeader("Content-Type",contentype);

    QByteArray sendArray = QJsonDocument(requestJson).toJson(QJsonDocument::Compact);
    QEventLoop eventLoop;
    QNetworkReply *reply = m_networkManger.post(networkRequest , sendArray);
    connect(&m_networkManger, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), &eventLoop, SLOT(quit()));
    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &eventLoop, SLOT(quit()));
    connect(this, &ThreadSocket::quit, &eventLoop,&QEventLoop::quit);
    // 加用定时器防止网络出现异常长时间不返回导致的阻塞
    QTimer::singleShot(SOCKET_POST_TIMEOUT, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

   if(reply->error() != QNetworkReply::NoError)
   {
       error = reply->errorString();
       return false;
   }

   QByteArray recvArray = reply->readAll();
   if(recvArray.size() == 0)
   {
       error = "Nothing Recved";
       QLOG_ERROR() << "S_PostRequest  Nothing Recved ";
       return false;
   }
   recvJson = QJsonDocument::fromJson(recvArray).object();
   QLOG_DEBUG() << "S_PostRequest: "<<recvJson;
   reply->deleteLater();

   return true;
}

bool ThreadSocket::S_GetRequest(const QString &url, QByteArray &out, QString &error)
{
    QNetworkAccessManager m_networkManger;

    if(QNetworkAccessManager::Accessible != m_networkManger.networkAccessible())
    {
        m_networkManger.setNetworkAccessible(QNetworkAccessManager::Accessible);
    }

    QLOG_INFO() << "S_GetRequest  Begin Get ............ ";
    QNetworkRequest networkRequest;
    networkRequest.setUrl(url);
    QEventLoop eventLoop;
    QNetworkReply *reply = m_networkManger.get(networkRequest);
    connect(&m_networkManger, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), &eventLoop, SLOT(quit()));
    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &eventLoop, SLOT(quit()));
    connect(this, &ThreadSocket::quit, &eventLoop,&QEventLoop::quit);
    // 加用定时器防止网络出现异常长时间不返回导致的阻塞
    QTimer::singleShot(SOCKET_GET_TIMEOUT, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

   if(reply->error() != QNetworkReply::NoError) {
       error = reply->errorString();
       QLOG_ERROR() << "S_GetRequest  Error: " << error;
       reply->close();
       reply->deleteLater();
       return false;
   }

   QLOG_INFO() << "S_GetRequest  Begin reply->readAll() ............ ";
   QByteArray recvArray = reply->readAll();
   // 需要设置超时时间，防止程序 右键退出后，无法释放资源，导致后端进程还在运行;
   if(recvArray.size() == 0) {
       error = "Nothing Recved";
       QLOG_ERROR() << "S_GetRequest  Nothing Recved ";
       reply->close();
       reply->deleteLater();
       return false;
   }

   out = recvArray;
   QLOG_DEBUG() << "S_GetRequest Success";
   reply->close();
   reply->deleteLater();
   return true;
}

void ThreadSocket::threadStart()
{
    _stoped = true;
}
