/*
 *  Copyright (C) 2007-2008 CMM Sigma Andrzej Chmielowiec <cmmsigma@cmmsigma.eu>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 */

// DirectoryArchiver.cpp: implementation of the DirectoryArchiver class.
//
//////////////////////////////////////////////////////////////////////

#include "DirectoryArchiver.h"
#include <QDir>

DirectoryArchiver::DirectoryArchiver()
{

}


DirectoryArchiver::~DirectoryArchiver()
{

}


bool DirectoryArchiver::archiveFiles(QString path, QXmlStreamWriter &xml)
{
	bool result = true;

	QDir dir = QDir(path);
	QFileInfoList fil = dir.entryInfoList(QDir::Files | QDir::AllDirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDir::Name);

	foreach(QFileInfo fi, fil)
	{
		if(fi.isDir())
		{
			xml.writeStartElement("DIR");
			xml.writeAttribute("name", fi.fileName());
			
			archiveFiles(fi.absoluteFilePath(), xml);

			xml.writeEndElement();
		}
		else
		{
			QFile file(fi.filePath());
			if(file.open(QFile::ReadOnly))
			{
				xml.writeStartElement("FILE");
				xml.writeAttribute("name", fi.fileName());
				xml.writeAttribute("body", QString(file.readAll().toBase64()));
				xml.writeEndElement();

				file.close();
			}
			else
				result = false;
		}
	}

	return result;
}


bool DirectoryArchiver::archive(QString directory, QString xmlFile, QString name)
{
	bool result = true;

	QFile file(xmlFile);
	result = file.open(QIODevice::WriteOnly);
	if(result)
	{
		QXmlStreamWriter xml(&file);
		xml.setAutoFormatting(true);

		xml.writeStartDocument();
		xml.writeStartElement("CA_BACKUP");

		if(!name.isEmpty())
			xml.writeAttribute("ca_name", name);
		
		result = archiveFiles(directory, xml);

		xml.writeEndElement();
		xml.writeEndDocument();

		file.close();
	}

	return result;
}


bool DirectoryArchiver::unarchiveFiles(QString path, QXmlStreamReader &xml)
{
	bool result = true;

	while (!xml.atEnd())
	{
		xml.readNext();
		QString xname = xml.name().toString();

		if(xml.isStartElement())
		{
			QXmlStreamAttributes atts = xml.attributes();
			QString name = atts.value("name").toString();

			if(!name.isEmpty())
			{
				if(xname == "DIR")
				{
					QString subPath = path + QDir::separator() + name;
					QDir dir;
					if(!dir.exists(subPath))
						result = dir.mkdir(subPath);
					else
						result = true;
					if(result)
						result = unarchiveFiles(subPath, xml);
				}
				else if(xname == "FILE")
				{
					if(!name.isEmpty())
					{
						QByteArray body = QByteArray::fromBase64(QByteArray(atts.value("body").toString().toUtf8()));
						QFile file(path + QDir::separator() + name);

						if(file.open(QIODevice::WriteOnly))
						{
							file.write(body);
							file.close();
						}
						else
							result = false;
					}
				}
			}
		}
		else if(xml.isEndElement() && xname == "DIR")
			return true;
	}

	if (xml.hasError())
	{
		result = false;
	}

	return result;
}


bool DirectoryArchiver::unarchive(QString directory, QString xmlFile, QString name)
{
	bool result = true;
	
	QFile file(xmlFile);
	result = file.open(QIODevice::ReadOnly);
	if(result)
	{
		QXmlStreamReader xml(&file);
		
		while (!xml.atEnd())
		{
			xml.readNext();
			QString xname = xml.name().toString();

			if(xml.isStartElement() && xname == "CA_BACKUP")
			{
				if(name.isEmpty())
				{
					QXmlStreamAttributes atts = xml.attributes();
					name = atts.value("ca_name").toString();
				}

				QString subPath = directory + QDir::separator() + name;
				QDir dir;
				if(!dir.exists(subPath))
					result = dir.mkdir(subPath);
				else
					result = true;

				if(result)
					result = unarchiveFiles(subPath, xml);
			}
			
		}
		if (xml.hasError())
		{
			result = false;
		}

		file.close();
	}

	return result;
}


bool DirectoryArchiver::checkFile(QString xmlFile, QString &name)
{
	bool result = true;
	
	QFile file(xmlFile);
	result = file.open(QIODevice::ReadOnly);
	if(result)
	{
		QXmlStreamReader xml(&file);
		
		while (!xml.atEnd())
		{
			xml.readNext();
			QString xname = xml.name().toString();

			if(xml.isStartElement())
			{
				if(xname == "CA_BACKUP")
				{
					QXmlStreamAttributes atts = xml.attributes();
					name = atts.value("ca_name").toString();
					break;
				}
			}
		}
		if (xml.hasError())
		{
			result = false;
		}

		file.close();
	}

	return result;
}
