#include "assetsmanager.h"

AssetsManager::AssetsManager(QObject *parent) : QObject(parent)
{

}

void AssetsManager::initialize(UpdateController* updateContoller,DataParser *dataParser)
{
    this->updateController = updateContoller;
    //connect(this,&AssetsManager::sigSaveVersion,updateContoller,&UpdateController::saveVersionToFile);
    datas = new QList<StreamingVersionData*>;
}

void AssetsManager::fillDatas()
{
    QByteArray array;
    QFile file(versionListFile);

    if(!file.exists())
    {
        return;
    }

    datas->clear();

    file.open(QIODevice::ReadOnly);
    array = file.readAll();
    file.close();
    QXmlStreamReader xmlReader(array);

    xmlReader.readNext();
    QString name = xmlReader.name().toString();

    while(!xmlReader.atEnd())
    {
        name = xmlReader.name().toString();

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

    if(xmlReader.name() == "VersionList")
    {
        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->setViewName(value);
                        else if(name == "Created")
                            data->setCreateData(QDateTime::fromString(value));
                        else if(name == "isChangeable")
                            data->setIsChangeable(value.toInt());
                        else if(name == "author")
                            data->setAuthor(value);

                    }

                    datas->append(data);
                }
            }

            xmlReader.readNext();
        }
      }
    }
}

void AssetsManager::setVersionList(QList<StreamingVersionData*> *streamingVersion)
{
    datas->clear();
    datas = streamingVersion;
}

bool AssetsManager::findDuplicate(QString name)
{
    QListIterator<StreamingVersionData*> iterator(*datas);

    while (iterator.hasNext())
    {
        if (iterator.next()->getViewName() == name) return true;
    }

    return false;
}

QString AssetsManager::setVersion(QString versionName)
{
    QListIterator<StreamingVersionData*> iterator(*datas);

    while (iterator.hasNext())
    {
        StreamingVersionData *version = iterator.next();

        if (version->getViewName() == versionName)
        {
            currentVersionData = version;
            saveVersionToFile(currentVersionData);

            return version->getAbsolutPath();
        }
    }

    return "none";
}

QList<FileData> *AssetsManager::prepareLocalPathList(QList<FileData> *fileData)
{
    QList<FileData> *completeList = fileData;

    for(int i = 0; i < completeList->count();i++)
    {
        FileData fileData = completeList->at(i);

        int index = fileData.path.indexOf(currentVersionData->getViewName());
        if(index != -1)
        {
            fileData.path = Tools::createRealPath(fileData.path,currentVersionData); //делаем в полный путь
            completeList->replace(i,fileData);
        }
        else
        {
            fileData.path = Tools::createRootPath(fileData.path);
        }

    }

    return completeList;
}

QList<FileData> *AssetsManager::prepareRealPathList(QList<FileData> *fileData)
{
    QList<FileData> *completeList = fileData;

    for(int i = 0; i < completeList->count();i++)
    {
        FileData fileData = completeList->at(i);
        if(fileData.path.contains(streamingAssetsFolderName))
        {
            fileData.path = Tools::createStreamingToRealPath(fileData.path,currentVersionData);
        }
        else
        {
            fileData.path = Tools::createRealPath(fileData.path,currentVersionData); //делаем в полный путь
        }

        completeList->replace(i,fileData);
    }

    return completeList;
}

void AssetsManager::addVersion(StreamingVersionData *data)
{
    datas->push_back(data);
}

void AssetsManager::createCopyVersion(QString versionName,QString newVersionName,QString author)
{
    qDebug() << "assetManager thread ID " << QThread::currentThreadId();
    StreamingVersionData* data = new StreamingVersionData;

    data->setAbsolutePath(Tools::createSharedPath("/" + newVersionName));
    data->setAuthor(author);
    data->setIsChangeable(true);
    data->setViewName(newVersionName);
    data->setCreateData(QDateTime::currentDateTime());
    datas->append(data);

    qDebug() << "Version for copy " << versionName;
    qDebug() << "New version name " << newVersionName;

    //берем путь до копии
    //преобразуем в реальный путь
    QString sourcePath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + versionName;
    QString destinationPath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + newVersionName;

    QDir sourceDir(sourcePath);

    if(!sourceDir.exists())
    {
        qDebug() << "Версии нет в SharedData";
        return;
    }

    QDir destinationDir(destinationPath);
    if(destinationDir.exists())
    {
        qDebug() << "Папка уже существует";
        return;
    }

    //Создаем папку в Shared с новым именем
    QDir().mkdir(destinationPath);
    copyAllRecurse(sourcePath,destinationPath);
    //добавляем в список текущих ассетов
    updateController->calculateFullHash();
    updateController->changeAssetVersion(newVersionName);
    updateController->sendNewVersionList();
    //повторно отправляем список версий из папки shared

}

void AssetsManager::deleteVersion(QString versionName)
{
    QMutableListIterator<StreamingVersionData*> iterator(*datas);

    //если версия равна текущей - игнор
    if (currentVersionData->getViewName() == versionName)
        return;

    while (iterator.hasNext())
    {
        StreamingVersionData *version = iterator.next();

        //проверка на наличие указанной версии
        if (version->getViewName() == versionName)
        {
            //удаление папки
            QString verFolderPath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + versionName;
            QDir dir(verFolderPath);
            dir.removeRecursively();

            //удаление хэша
            QString hashPath = QDir::currentPath() + "/" + staticDataFolderName + "/" + versionName + "Hash.xml";
            QFile file(hashPath);

            if(file.exists()){
                file.remove();
            }

            //удаление
            datas->removeOne(version);
            break;
        }
    }

    updateController->calculateSharedHash();
    updateController->sendNewVersionList();
}

void AssetsManager::copyAllRecurse(QString source,QString destination)
{

    //Копируем все объекты туда
    QDir sourceDir(source);

    foreach(QString folder,sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
    {
        QString destPath = destination + QDir::separator() + folder;
        sourceDir.mkpath(destPath);
        copyAllRecurse(source + QDir::separator() + folder,destPath);
    }

    foreach(QString file,sourceDir.entryList(QDir::Files))
    {
        QFile::copy(source + QDir::separator() + file,destination + QDir::separator() + file);
    }
}

void AssetsManager::writeVersionsToFile(QList<StreamingVersionData*> version,bool isFirst)
{
    QList<SXmlAnswerTag> listTag;
    datas->clear();
    QFile file(versionListFile);

    foreach(StreamingVersionData* ver,version)
    {
        SAttribute attribute1 = {"Version", ver->getViewName()};
        SAttribute attribute2 = {"Created", ver->getCreateData().toString()};
        SAttribute attribute3;
        SAttribute attribute4;

        if(isFirst)
        {
            attribute3 = {"isChangeable",QString::number(false)};
            QString author = tr("LLC Constanta-Design");
            attribute4 = {"author",author};
            ver->setAuthor(author);
        }else
        {
            attribute3 ={"isChangeable",QString::number(ver->getIsChangeable())};
            attribute4 = {"author",ver->getAuthor()};
        }


        QList<SAttribute> listAttr = {attribute1, attribute2,attribute3,attribute4};
        SXmlAnswerTag tag = {"VersionData", listAttr};

        listTag.append(tag);
        datas->append(ver);
    }

    file.open(QIODevice::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("VersionList");

    foreach(SXmlAnswerTag tag,listTag)
    {
        xmlWriter.writeStartElement(tag.elementName);

        foreach(SAttribute attribute,tag.attr)
        {
            xmlWriter.writeAttribute(attribute.name,attribute.value);
        }

        xmlWriter.writeEndElement();
    }

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

void AssetsManager::createFirstVersionListXML(QList<StreamingVersionData*> version)
{
    QFile file(versionListFile);
    QList<StreamingVersionData*> *temp = new QList<StreamingVersionData*>();
    if(!file.exists())
    {
        writeVersionsToFile(version,true);
    }
    else
    {

        if(datas->count() == 0) fillDatas();

        foreach(StreamingVersionData* ver,version)
        {
            foreach(StreamingVersionData* data,*datas)
            {
                if(ver->getViewName() == data->getViewName())
                {
                    StreamingVersionData *tempData = new StreamingVersionData;

                    tempData->fill(data);
                    tempData->setAbsolutePath(ver->getAbsolutPath());
                    temp->append(tempData);

                    break;
                }
            }
        }

        writeVersionsToFile(*temp,false);
    }

}

void AssetsManager::saveVersionToFile(StreamingVersionData *streamingVersion)  //TODO: переименовать и перебросить в AssetManager
{
    QFile file(version);
    file.open(QFile::WriteOnly);

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();

    xmlWriter.writeStartElement("VersionData");
    xmlWriter.writeAttribute("Version",streamingVersion->getViewName());
    xmlWriter.writeAttribute("Created",streamingVersion->getCreateData().toString());
    xmlWriter.writeAttribute("isChangeable",QString::number(streamingVersion->getIsChangeable()));
    xmlWriter.writeAttribute("author",streamingVersion->getAuthor());

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

    file.close();
}

AssetsManager::~AssetsManager()
{

}

StreamingVersionData *AssetsManager::getCurrentVersionData() const
{
    return currentVersionData;
}

