#include "Core/dataparser.h"

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

#include <QDir>
#include <QDomDocument>

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

void DataParser::initialize(RecognizeSystem *recognizeSystem)
{
    this->recognizeSystem = recognizeSystem;
}

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();
}

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

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

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

    xmlWriter.writeAttribute("Login",auth->Login);
    xmlWriter.writeAttribute("Password",auth->Password);

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

    file.close();
}

void DataParser::createServerSettings(ServerSettings* serverSettings)
{
    QFile file(settingsName);

    file.open(QIODevice::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);

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

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

    xmlWriter.writeAttribute("Address",serverSettings->Address);
    xmlWriter.writeAttribute("Port",serverSettings->Port);
    xmlWriter.writeAttribute("Language","RUS");
    xmlWriter.writeAttribute("AutoStart",QString::number(false));

    xmlWriter.writeEndElement();
    xmlWriter.writeStartElement("VersionData");
    xmlWriter.writeAttribute("Version","NONE");
    xmlWriter.writeEndElement();

    xmlWriter.writeEndElement();

    xmlWriter.writeEndDocument();

    file.close();

}

void DataParser::changeVersion(QString versionName)
{
    QFile file(settingsName);

    file.open(QIODevice::ReadWrite);
    QByteArray xmlData(file.readAll());

    QDomDocument doc;
    doc.setContent(xmlData);
    QDomElement containerElement = doc.firstChildElement("ServerSettingsContainer");
    QDomElement verDataElement = containerElement.firstChildElement("VersionData");
    verDataElement.setAttribute("Version",versionName);

    file.resize(0);
    QTextStream out(&file);
    doc.save(out,4);

    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.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;
}

void DataParser::xmlParser(QByteArray array)
{
    QXmlStreamReader xmlReader(array);

    xmlReader.readNext();

    while(!xmlReader.atEnd())
    {
        if(!xmlReader.isStartElement()) {
            xmlReader.readNext();
            continue;
        }

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

                if(name == "Code")
                {
                    if (value == "END")
                    {
                        emit recognizeSystem->sigSocketDisabled();
                    }

                    if(value == "BLOCKED")
                    {
                        emit recognizeSystem->sigServerBlocked();
                    }

                    if(value == "HASHSENDCOMPLETE")
                    {
                        emit recognizeSystem->sigStartCompare();
                    }
                }
            }
        }

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

            ServerAuthorization *serverAuth = new ServerAuthorization;

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

                if (name == "Result"){
                    serverAuth->Result = value == "true" ? true : false;
                }

                if (name == "InstructorName"){
                    serverAuth->InstructorName = value;
                }

                if (name == "ClientName"){
                    serverAuth->ClientName = value;
                }

                if (name == "AccessType"){
                    serverAuth->AccessType = value;
                    recognizeSystem->checkAccessType(value);
                }
            }

            emit recognizeSystem->sigSaveLoginData(serverAuth);
        }

        if(xmlReader.name() == "VersionData")
        {
            StreamingVersionData *serverVersion = new StreamingVersionData;
            foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
            {
                QString name = attr.name().toString();
                QString value = attr.value().toString();

                if(name == "Version")
                {
                    serverVersion->setName(value);
                }

                if(name == "Created")
                {
                    serverVersion->setCreateData(QDateTime::fromString(value));
                }

            }
            recognizeSystem->setServerVersion(serverVersion);
        }

        if(xmlReader.name() == "VersionList")
        {
            QList<StreamingVersionData*> *serverStreamingVersionDataList = new QList<StreamingVersionData*>;
            xmlReader.readNext();

            while (!xmlReader.atEnd())
            {
                if(xmlReader.isStartElement())
                {
                    if(xmlReader.name() == "VersionData")
                    {
                        StreamingVersionData *data = new StreamingVersionData;

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

                            if(name == "Version")
                                data->setName(value);
                            else if(name == "Created")
                                data->setCreateData(QDateTime::fromString(value));
                        }

                        serverStreamingVersionDataList->append(data);
                    }
                }

                xmlReader.readNext();
            }
            recognizeSystem->showServerDataList(serverStreamingVersionDataList);
        }

        xmlReader.readNext();
    }
}

DataParser::~DataParser()
{

}
