#include "clienthandler.h"

#include <QThread>

#include <Systems/sendsystem.h>

ClientHandler::ClientHandler( QObject *parent):
    QObject(parent)
{
}

void ClientHandler::initialize(int descriptor,ServerLMSWidget *serverWidget,
    UpdateController *updateController,DataParser *dataParser,Logger *logger)
{
    this->socket = new QTcpSocket;
    this->thread = new QThread;

    socket->setParent(nullptr);
    socket->setSocketDescriptor(descriptor);

    qDebug() << "Client thread: " << QThread::currentThreadId();

    sendSystem = new SendSystem;
    recognizeSystem = new RecognizeSystem;

    thread->start();

    socket->moveToThread(thread);
    sendSystem->moveToThread(thread);
    recognizeSystem->moveToThread(thread);

    this->updateController = updateController;
    this->server = serverWidget;

    QString peerName = socket->peerName();
    QString peerAddress = socket->peerAddress().toString();
    QString peerPort = QString::number(socket->peerPort());

    client = new Client(peerName,peerAddress,peerPort,socket);

    connect(this,&ClientHandler::sigSendXmlAnswer,sendSystem,&SendSystem::sendXmlAnswer,Qt::AutoConnection);
    connect(this,&ClientHandler::sigInitSender,sendSystem,&SendSystem::initialize,Qt::AutoConnection);
    connect(this,&ClientHandler::sigFileBlock,sendSystem,&SendSystem::sendFileBlock,Qt::AutoConnection);
    connect(this,&ClientHandler::sigFolderBlock,sendSystem,&SendSystem::sendFolderBlock,Qt::AutoConnection);
    connect(this,&ClientHandler::sigGetIsSendStopped,sendSystem,&SendSystem::getIsSendStopped,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSendDeleteBlock,sendSystem,&SendSystem::sendDeleteBlock,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSendFinish,sendSystem,&SendSystem::sendFinish,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSendMessageBlock,sendSystem,&SendSystem::sendMessageBlock,Qt::AutoConnection);
    connect(this,&ClientHandler::sigNeedUpdate,sendSystem,&SendSystem::sendNeedUpdate,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSendNotify,sendSystem,&SendSystem::sendNotify,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSendFileBlockWithRename,sendSystem,&SendSystem::sendFileBlockWithRename,Qt::AutoConnection);
    connect(socket,&QTcpSocket::readyRead,recognizeSystem,&RecognizeSystem::recognize,Qt::AutoConnection);
    connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::sendDisable,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSocketWrite,sendSystem,&SendSystem::socketWrite,Qt::AutoConnection);
    connect(this,&ClientHandler::sigSocketClose,sendSystem,&SendSystem::socketClose,Qt::AutoConnection);


    recognizeSystem->initialize(updateController,dataParser,serverWidget,sendSystem, this);
    sendSystem->setClient(client,socket);

    connect(recognizeSystem,&RecognizeSystem::sigSendToLogger,logger,&Logger::addTextToLogger);
    emit sigInitSender(dataParser,logger);
}

void ClientHandler::sendHash()
{
    QString path = "\\" + hashFileName;
    emit sigSendFileBlockWithRename(path,"/serverHash.xml");
    //emit sigSendNotify("HASHSENDCOMPLETE");
}

void ClientHandler::sendXmlAnswer(QByteArray array)
{
    emit sigSendXmlAnswer(array);
}

void ClientHandler::sendFolderBlock(QString path)
{
    emit sigFolderBlock(path);
}

void ClientHandler::sendFileBlock(QString path)
{
    emit sigFileBlock(path);
}

bool ClientHandler::getIsSendStopped()
{
    return emit sigGetIsSendStopped();
}

void ClientHandler::sendDeleteBlock(QString path)
{
    emit sigSendDeleteBlock(path);
}

void ClientHandler::sendFinish()
{
    emit sigSendFinish();
}

void ClientHandler::sendMessageBlock(QString text)
{
    emit sigSendMessageBlock(text);
}

void ClientHandler::sendNeedUpdate(bool flag, quint64 size, quint64 fileCount)
{
    emit sigNeedUpdate(flag,size,fileCount);
}

void ClientHandler::sendDisable()
{
    thread->exit();
    thread->wait();
    emit sigClientDisconnected(client->getAddress(),client->getPort());

}

Client *ClientHandler::getClient() const
{
    return client;
}

SendSystem *ClientHandler::getSendSystem() const
{
    return sendSystem;
}

QTcpSocket *ClientHandler::getSocket() const
{
    return socket;
}

ClientHandler::~ClientHandler()
{
    thread->quit();
    thread->wait();
}
