#include "Core/dataparser.h"

#include "FileData.h"
#include "tools.h"

#include "instructor.h"
#include "trainee.h"
#include "group.h"
#include "tasksAmmFim.h"
#include "streamingversiondata.h"

#include <QDir>

DataParser::DataParser(QObject *parent) :
    QObject(parent)
{
    if(!QDir(staticDataFolderName).exists()){
        QDir().mkdir(staticDataFolderName);
    }
}

QByteArray DataParser::slotGetXmlAnswer(QString answerCode)
{
    if(answerCode == "END"){
        return xmlAnswer_notify(answerCode);
    }
    return nullptr;
}

void DataParser::createFileDataList(QList<FileData> fileDataList,QString filename)
{

    QFile file(filename);
    file.open(QIODevice::WriteOnly);
    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("FileDataList");

    foreach (FileData data,fileDataList)
    {
        xmlWriter.writeStartElement("FileData");

        xmlWriter.writeAttribute("Path",data.path);
        xmlWriter.writeAttribute("Hash",data.hash);

        xmlWriter.writeEndElement();
    }

    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    file.close();
}

QByteArray DataParser::createAuthMessage(ClientAutorization *auth)
{
    authPassCache = auth; //кэширование даных авторизации, для сохранения при успешном заходе

    QByteArray array;
    QXmlStreamWriter xmlWriter(&array);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("ClientAutorization");

    xmlWriter.writeAttribute("Login", auth->Login);
    xmlWriter.writeAttribute("Password", auth->Password);
    xmlWriter.writeAttribute("TypeClient", QString::number(auth->TypeClient));

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    return array;
}

QByteArray DataParser::createMessage(ClientMessage clientMessage)
{
    QByteArray array;
    QXmlStreamWriter xmlWriter(&array);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("ClientMessage");

    xmlWriter.writeAttribute("From",clientMessage.fromId);
    xmlWriter.writeAttribute("To", clientMessage.toId);
    xmlWriter.writeAttribute("Text", clientMessage.Text);

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    return array;
}



QByteArray DataParser::createQueryToDBMessage(ClientQueryToDB *queryToDB, int id, void* data)
{
    QByteArray array;
    QXmlStreamWriter xmlWriter(&array);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("QueryToDB");

    xmlWriter.writeAttribute("TypeQuery", QString::number(queryToDB->typeQuery));

    if(id)
        xmlWriter.writeAttribute("id", QString::number(id));

    if(data)
    {
        if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR ||
                queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR)
        {
            Instructor* instructor = (Instructor*)data;
            if(instructor)
            {
                xmlWriter.writeAttribute("instructor_id", QString::number(instructor->getID()));
                xmlWriter.writeAttribute("name", instructor->getName());
                xmlWriter.writeAttribute("login", instructor->getLogin());
                xmlWriter.writeAttribute("password", instructor->getPassword());
                xmlWriter.writeAttribute("is_admin", QString::number(instructor->getIsAdmin()));
                xmlWriter.writeAttribute("archived", QString::number(instructor->getArchived()));
                xmlWriter.writeAttribute("logged_in", QString::number(instructor->getLoggedIn()));
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE)
        {
            Trainee* trainee = (Trainee*)data;
            if(trainee)
            {
                xmlWriter.writeAttribute("trainee_id", QString::number(trainee->getID()));
                xmlWriter.writeAttribute("name", trainee->getName());
                xmlWriter.writeAttribute("login", trainee->getLogin());
                xmlWriter.writeAttribute("password", trainee->getPassword());
                xmlWriter.writeAttribute("archived", QString::number(trainee->getArchived()));
                xmlWriter.writeAttribute("logged_in", QString::number(trainee->getLoggedIn()));
                xmlWriter.writeAttribute("group_trainee", QString::number(trainee->getGroup().getID()));
                xmlWriter.writeAttribute("computer_trainee", QString::number(trainee->getComputer().getID()));
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE)
        {
            Trainee* trainee = (Trainee*)data;
            if(trainee)
            {
                xmlWriter.writeAttribute("trainee_id", QString::number(trainee->getID()));
                xmlWriter.writeAttribute("name", trainee->getName());
                xmlWriter.writeAttribute("login", trainee->getLogin());
                xmlWriter.writeAttribute("password", trainee->getPassword());
                xmlWriter.writeAttribute("archived", QString::number(trainee->getArchived()));
                xmlWriter.writeAttribute("logged_in", QString::number(trainee->getLoggedIn()));
                xmlWriter.writeAttribute("group_trainee", QString::number(id));
                xmlWriter.writeAttribute("computer_trainee", QString::number(trainee->getComputer().getID()));
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_EDIT_GROUP ||
                queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_NEW_GROUP)
        {
            Group* group = (Group*)data;
            if(group)
            {
                xmlWriter.writeAttribute("group_id", QString::number(group->getID()));
                xmlWriter.writeAttribute("name", group->getName());
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE)
        {
            TaskAmmFim* task = (TaskAmmFim*)data;
            if(task)
            {
                xmlWriter.writeAttribute("title", task->ammProcedure.title);
                xmlWriter.writeAttribute("dmCode", task->ammProcedure.dmCode);
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE)
        {
            TaskAmmFim* task = (TaskAmmFim*)data;
            if(task)
            {
                xmlWriter.writeAttribute("title", task->title);

                for(Malfunction malfunction : task->malfunctionList)
                {
                    xmlWriter.writeStartElement("malfunction");
                    xmlWriter.writeAttribute("dmCode", malfunction.dmCode);
                    xmlWriter.writeAttribute("num", malfunction.num);
                    xmlWriter.writeAttribute("description", malfunction.description);                    

                    for(MalfunctionSign sign : malfunction.malfunctionSigns)
                    {
                        xmlWriter.writeStartElement("malfunctionSign");
                        xmlWriter.writeAttribute("type", QString::number(sign.type));
                        xmlWriter.writeAttribute("description", sign.description);
                        xmlWriter.writeEndElement();
                    }

                    xmlWriter.writeEndElement();
                }
            }
        }
        else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_AMM_TO_TRAINEE ||
                queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_FIM_TO_TRAINEE)
        {
            QString* status = (QString*)data;
            if(status)
            {
                xmlWriter.writeAttribute("status", *status);
            }
        }
    }

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    QFile file("QueryToDB.xml");
    file.open(QIODevice::WriteOnly);
    file.write(array);
    file.close();

    return array;
}

QByteArray DataParser::createQueryTasksXMLMessage(QString type)
{
    QByteArray array;
    QXmlStreamWriter xmlWriter(&array);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("QueryTasksXML");

    xmlWriter.writeAttribute("Type", type);

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    return array;
}

QByteArray DataParser::createDeAuthMessage(ClientDeAutorization *deAuth)
{
    QByteArray array;
    QXmlStreamWriter xmlWriter(&array);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("ClientDeAutorization");

    xmlWriter.writeAttribute("Login",deAuth->Login);

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    return array;
}



void DataParser::createServerSettings(QString address, QString port)
{
    QFile file(settingsName);

    file.open(QIODevice::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();

    xmlWriter.writeStartElement("ServerSettingsContainer");
    xmlWriter.writeStartElement("ServerSettings");

    xmlWriter.writeAttribute("Address",address);
    xmlWriter.writeAttribute("Port",port);
    xmlWriter.writeAttribute("Language","RUS");
    xmlWriter.writeAttribute("AutoStart",QString::number(false));

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();

    xmlWriter.writeEndDocument();

    file.close();

}

void DataParser::createAuthData(ServerAuthorization *serverAuth)
{
    QFile file(authTempName);
    file.open(QIODevice::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("AuthData");
    xmlWriter.writeAttribute("Login",authPassCache->Login);
    xmlWriter.writeAttribute("Password",authPassCache->Password);
    xmlWriter.writeAttribute("InstructorName",serverAuth->InstructorName);
    xmlWriter.writeAttribute("ClientName",serverAuth->ClientName);
    xmlWriter.writeAttribute("AccessType",serverAuth->AccessType);
    xmlWriter.writeAttribute("id_client",serverAuth->Id);
    xmlWriter.writeEndElement();
    file.close();

}

void DataParser::createAuthDataOffline(QString username, QString pass)
{
    QFile file(authTempName);
    file.open(QIODevice::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("AuthData");
    xmlWriter.writeAttribute("Login",username);
    xmlWriter.writeAttribute("Password",pass);
    xmlWriter.writeAttribute("InstructorName","empty");
    xmlWriter.writeAttribute("ClientName","Offline");
    xmlWriter.writeAttribute("AccessType","Offline");

    xmlWriter.writeEndElement();
    file.close();
}

QByteArray DataParser::xmlAnswer_notify(QString code)
{

    QList<SXmlAnswerTag> listTag;

    SAttribute attribute1 = {"Code", code};
    QList<SAttribute> listAttr = {attribute1};
    SXmlAnswerTag tag = {"ClientNotify", listAttr};

    listTag.append(tag);

    return xmlAnswer(listTag);
}

void DataParser::addRunData(QList<int> displays)
{
    QFile file(displayTemp);
    file.open(QIODevice::ReadWrite);

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartElement("DisplayInfo");
    xmlWriter.writeAttribute("DisplayCount",QString::number(displays.length()));
    xmlWriter.writeEndElement();
    file.close();

}

ServerSettings *DataParser::getServerSettings()
{
    ServerSettings *settings = new ServerSettings;
    QFile file(settingsName);
    file.open(QIODevice::ReadOnly);
    QXmlStreamReader xmlReader(&file);

    while (!xmlReader.atEnd()){

        if(xmlReader.isStartElement()){

            if(xmlReader.name() == "ServerSettings")
            {

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

                    if(name == "Address"){
                        settings->Address = value;
                    }

                    if(name == "Port"){
                        settings->Port = value;
                    }

                    if(name == "Language"){
                        settings->Language = value;
                    }

                    if(name == "AutoStart"){
                        settings->isAutoStart = value.toInt();
                    }

                }
            }
        }

        xmlReader.readNext();
    }

    file.close();
    return settings;
}

void DataParser::saveClientSettrings(QString language, bool isAutoStart)
{
    QFile file(settingsName);
    file.open(QIODevice::ReadOnly | QIODevice::Text);

    QString settings = file.readAll();

    file.close();
    file.remove();

    file.open(QIODevice::WriteOnly | QIODevice::Text);

    auto languagePos = settings.indexOf(XMLLanguageProperty) + XMLLanguageProperty.length();
    settings = settings.replace(languagePos,language.size(),language);

    auto autoStartPos = settings.indexOf(XMLAutoStartProperty) + XMLAutoStartProperty.length();
    settings = settings.replace(autoStartPos,1,QString::number(isAutoStart));

    file.write(settings.toUtf8());
    file.close();
}

QList<FileData>* DataParser::xmlFileDataParse(QByteArray array, QString filter = "")
{
    QXmlStreamReader xmlReader(array);
    QList<FileData> *datas = new QList<FileData>;
    xmlReader.readNext();   // Переходим к первому элементу в файле

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

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

                    if(name == "Path")
                        data.path = value;
                    else if(name == "Hash")
                        data.hash = value;
                }

                if(data.path.contains(filter))

                datas->append(data);
            }
        }

        xmlReader.readNext();
    }

    return datas;
}

QByteArray DataParser::xmlAnswer(QList<SXmlAnswerTag> listTag, QString elemUp1, QString elemUp2)
{
    /* Открываем файл для Записи*/
    QFile file(tempName);
    file.open(QIODevice::WriteOnly);

    /* Создаем объект, с помощью которого осуществляется запись в файл */
    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);  // Устанавливаем автоформатирование текста

    xmlWriter.writeStartDocument();     // Запускаем запись в документ

    if(elemUp1 != "")
        xmlWriter.writeStartElement(elemUp1);   // Записываем тег

    if(elemUp2 != "")
        xmlWriter.writeStartElement(elemUp2);   // Записываем тег

    //Записываем все элементы
    foreach(SXmlAnswerTag tag, listTag)
    {
        xmlWriter.writeStartElement(tag.elementName);   // Записываем тег

        // Записываем атрибуты
        foreach(SAttribute attr, tag.attr)
            xmlWriter.writeAttribute(attr.name, attr.value);

        xmlWriter.writeEndElement();        // Закрываем тег
    }

    if(elemUp1 != "")
        xmlWriter.writeEndElement();        // Закрываем тег

    if(elemUp1 != "")
        xmlWriter.writeEndElement();        // Закрываем тег

    /* Завершаем запись в документ*/
    xmlWriter.writeEndDocument();

    file.close();   // Закрываем файл

    QByteArray array;

    /* Открываем файл для Чтения*/
    QFile fileR(tempName);
    if (!fileR.open(QFile::ReadOnly | QFile::Text))
    {
        QString str = "Не удалось открыть файл";
        qDebug() << "xmlAnswer: " << str;
    }
    else
    {
        array = fileR.readAll();
        fileR.close();   // Закрываем файл
    }

    return array;
}


DataParser::~DataParser()
{

}
