#include "processparser.h"
#include "tasksAmmFim.h"

ProcessParser::ProcessParser(QObject *parent) : QObject(parent)
{

}

void ProcessParser::initialize(ProcessingSystem *processingSystem)
{
    this->processingSystem = processingSystem;
}

void ProcessParser::read(ClientHandler *client, QByteArray array)
{
    QXmlStreamReader xmlReader(array);

    xmlReader.readNext();   // Переходим к первому элементу в файле

    //Крутимся в цикле до тех пор, пока не достигнем конца документа
    while(!xmlReader.atEnd())
    {
        //Проверяем, является ли элемент началом тега
        if(xmlReader.isStartElement())
        {
            //Анализируем теги
            if(xmlReader.name() == "ClientAutorization")
            {//Запрос авторизации от клиента

                clientAuth(xmlReader,client);
            }
            else if(xmlReader.name() == "ClientDeAutorization")
            {//Запрос ДеАвторизации от клиента

                clientDeAuth(xmlReader,client);
            }
            else if(xmlReader.name() == "ToClientMessage")
            {//Отправка сообщения Клиенту

                toClientMessage(xmlReader,client);
            }
            else if(xmlReader.name() == "QueryToDB")
            {//Запрос к базе данных от клиента

                queryToDb(xmlReader,client);
            }
            else if(xmlReader.name() == "QueryTasksXML")
            {//Запрос файла XML с задачами

                queryTasksXML(xmlReader,client);
            }
            else if(xmlReader.name() == "ClientMessage")
            {//Сообщение от клиента

                clientMessage(xmlReader,client);
            }
            else if(xmlReader.name() == "ClientNotify")
            {//Уведомление от клиента

                clientNotify(xmlReader,client);
            }
            else if(xmlReader.name() == "DataInfo")
            {
                  clientDataInfo(xmlReader,client);
            }
            else
            {
                emit sigLogMessage("XmlParser: unrecognized tag");
            }

        }
        xmlReader.readNext(); // Переходим к следующему элементу файла
    }//while(!xmlReader.atEnd())
}

void ProcessParser::clientDataInfo(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    DataInfo *dataInfo = new DataInfo;

    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();

        if(name == "path")
            dataInfo->path= value.toUtf8();

        if(name == "size")
            dataInfo->size = value.toLong();
    }

    processingSystem->setCurrentDataInfo(dataInfo);

}
void ProcessParser::clientAuth(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ClientAutorization clientAutorization;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "Login")
            clientAutorization.Login = value;
        else if(name == "Password")
            clientAutorization.Password = value;
        else if(name == "NumberOfScreen")
            clientAutorization.NumberOfScreen = value.toInt();
        else if(name == "TypeClient")
            clientAutorization.TypeClient = (TypeClientAutorization)value.toInt();
    }

    processingSystem->processingClientAutorization(client, clientAutorization);
}

void ProcessParser::clientDeAuth(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ClientDeAutorization clientDeAutorization;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "Login")
            clientDeAutorization.Login = value;
    }

    processingSystem->processingClientDeAutorization(client, clientDeAutorization);
}

void ProcessParser::toClientMessage(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ToClientMessage toClientMessage;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "id")
            toClientMessage.id = value.toInt();
        else if(name == "Text")
            toClientMessage.Text = value;
        else if(name == "Login")
            toClientMessage.Login = value;
    }

    processingSystem->processingToClientMessage(client, toClientMessage);
}

void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ClientQueryToDB queryToDB;
    int id = 0;
    Instructor instructor;
    Trainee trainee;
    Group group;
    TaskAmmFim task;
    void* data = nullptr;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "TypeQuery")
            queryToDB.typeQuery = (TypeQueryToDB)value.toInt();
        else if(name == "id")
            id = value.toInt();
        else
        {
            switch (queryToDB.typeQuery)
            {
            case TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR:
            case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
                if(name == "instructor_id")
                    instructor.setID(value.toInt());
                else if(name == "name")
                    instructor.setName(value);
                else if(name == "login")
                    instructor.setLogin(value);
                else if(name == "password")
                    instructor.setPassword(value);
                else if(name == "is_admin")
                    instructor.setIsAdmin(value.toInt());
                else if(name == "archived")
                    instructor.setArchived(value.toInt());
                else if(name == "logged_in")
                    instructor.setLoggedIn(value.toInt());
                break;
            case TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE:
            case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
                if(name == "trainee_id")
                    trainee.setID(value.toInt());
                else if(name == "name")
                    trainee.setName(value);
                else if(name == "login")
                    trainee.setLogin(value);
                else if(name == "password")
                    trainee.setPassword(value);
                else if(name == "archived")
                    trainee.setArchived(value.toInt());
                else if(name == "logged_in")
                    trainee.setLoggedIn(value.toInt());
                else if(name == "group_trainee")
                {
                    Group group(value.toInt(), "");
                    trainee.setGroup(group);
                }
                else if(name == "computer_trainee")
                {
                    Computer computer(value.toInt(), "", "", Classroom());
                    trainee.setComputer(computer);
                }
                break;
            case TypeQueryToDB::TYPE_QUERY_NEW_GROUP:
            case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
                if(name == "group_id")
                    group.setID(value.toInt());
                else if(name == "name")
                    group.setName(value);
                break;

            case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
                if(name == "title")
                    task.ammProcedure.title = value;
                else if(name == "dmCode")
                    task.ammProcedure.dmCode = value;
                break;
            case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
                if(name == "title")
                    task.title = value;
                break;
            };
        }
    }

    switch (queryToDB.typeQuery)
    {
    case TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR:
    case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
        data = &instructor;
        break;
    case TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE:
    case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
        data = &trainee;
        break;
    case TypeQueryToDB::TYPE_QUERY_NEW_GROUP:
    case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
        data = &group;
        break;
    case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
    case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
        data = &task;
        break;
    };

    processingSystem->processingClientQueryToDB(client, queryToDB, id, data);
}

void ProcessParser::queryTasksXML(QXmlStreamReader &xmlReader, ClientHandler *client)
{
    ClientQueryTasksXML clientQueryTasksXML;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "Type")
            clientQueryTasksXML.Type = value;
    }

    processingSystem->processingClientQueryTasksXML(client, clientQueryTasksXML);
}

void ProcessParser::clientMessage(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ClientMessage clientMessage;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();
        //addTextToLogger(name + ": " + value);

        if(name == "Text")
            clientMessage.Text = value;
    }

    processingSystem->processingFromClientMessage(client, clientMessage);

}

void ProcessParser::clientNotify(QXmlStreamReader &xmlReader,ClientHandler *client)
{
    ClientNotify clientNotify;

    /*Перебираем все атрибуты тега*/
    foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
    {
        QString name = attr.name().toString();
        QString value = attr.value().toString();

        if(name == "Code")
            clientNotify.Code = value;
    }



    processingSystem->processingClientNotify(client, clientNotify);
}


