/*
 * Resource.cpp
 *
 *  Created on: 14.07.2011
 *      Author: stefan.detter
 */

#include "Resource.h"

#include <QApplication>
#include <QDesktopServices>
#include <QSettings>
#include <QDir>

#include <def.h> 

Resource* 	Resource::d = 0;
QString 	Resource::_soundFilePath = QDir::home().path() + COMPANY_NAME + "\\SoundRepository";
QString 	Resource::_firmwareFilePath = QDir::home().path() + COMPANY_NAME + "\\FirmwareRepository";
QString 	Resource::_testFirmwareFilePath = QDir::home().path() + COMPANY_NAME + "\\TestFirmwareRepository";
QString 	Resource::_bootloaderFilePath = QDir::home().path() + COMPANY_NAME + "\\BootloaderRepository";

Resource::Resource(QObject* parent)
	: QObject(parent)
	, QrfeTraceModule("Resource")
{
#ifdef Q_OS_MACX
    QString fileName = QCoreApplication::applicationDirPath();
#else
    QSettings set(QSettings::IniFormat, QSettings::SystemScope, COMPANY_NAME);
    QString fileName = set.fileName();
    fileName.remove(".ini");
#endif


	_soundFilePath			= fileName + "/SoundRepository";
	_firmwareFilePath	 	= fileName + "/FirmwareRepository";
	_testFirmwareFilePath 	= fileName + "/TestFirmwareRepository";
	_bootloaderFilePath 	= fileName + "/BootloaderRepository";

	trc(0, "SoundRepository:         " + _soundFilePath);
	trc(0, "FirmwareRepository:      " + _firmwareFilePath);
	trc(0, "TestFirmwareRepository:  " + _testFirmwareFilePath);
	trc(0, "BootloaderRepository:    " + _bootloaderFilePath);

	qRegisterMetaType<Resource::ResourceType>("Resource::ResourceType");
}

Resource::~Resource()
{
}


void Resource::init()
{
	QDir dir;
	if(!dir.exists(_soundFilePath))
		dir.mkpath(_soundFilePath);
	if(!dir.exists(_firmwareFilePath))
		dir.mkpath(_firmwareFilePath);
	if(!dir.exists(_testFirmwareFilePath))
		dir.mkpath(_testFirmwareFilePath);
	if(!dir.exists(_bootloaderFilePath))
		dir.mkpath(_bootloaderFilePath);

	m_soundFiles 		= searchResourceFolders(_soundFilePath, QStringList() << "wav");
    m_firmwareFile	 	= searchResourceFolders(_firmwareFilePath, QStringList() << "idt");
    m_testFirmwareFile 	= searchResourceFolders(_testFirmwareFilePath, QStringList() << "idt");
    m_bootloaderFile 	= searchResourceFolders(_bootloaderFilePath, QStringList() << "idt");
}

void Resource::startImport()
{
	m_yesToAll = false;
}


QFileInfoList Resource::soundFiles()
{
	return m_soundFiles;
}

QFileInfoList Resource::firmwareFiles()
{
	return m_firmwareFile;
}

QFileInfoList Resource::testFirmwareFiles()
{
	return m_testFirmwareFile;
}

QFileInfoList Resource::bootloaderFiles()
{
	return m_bootloaderFile;
}

bool Resource::copyFileToResource ( const QFileInfo& file , const Resource::ResourceType& type, const QString& subDir, QFileInfo& newFile )
{
	QString repoDir;
	switch(type)
	{
	case Resource::SoundResource:
		repoDir += _soundFilePath;
		break;
	case Resource::FimrwareResource:
		repoDir += _firmwareFilePath;
		break;
	case Resource::TestFimrwareResource:
		repoDir += _testFirmwareFilePath;
		break;
	case Resource::BootloaderResource:
		repoDir += _bootloaderFilePath;
		break;
	}

	QString dirPath = repoDir + "/" + subDir;
	QDir targetDir(dirPath);
	if(!targetDir.exists()){
		targetDir.mkpath(dirPath);
	}

	QString targetFile = dirPath + "/" + file.fileName();
	if(QFile::exists(targetFile))
	{
		trc(1, "Target file " + targetFile + " exists, trying to rename..");

		if(!QFile::setPermissions(targetFile, (QFile::Permissions)0x7777))
		{
			trc(1, "Could not change permission...");
		}
		else
		{
			trc(1, "Permission changed...");
		}

		if(!QFile::rename(targetFile, targetFile + "_OLD"))
		{
			trc(1, "Could not rename...");
		}
		else
		{
			trc(1, "Rename succeeded...");
		}
	}


	if(!QFile::copy(file.absoluteFilePath(), targetFile))
	{
		trc(1, "Could not copy...");
		if(QFile::exists(targetFile + "_OLD"))
		{
			QFile::rename(targetFile + "_OLD", targetFile);
		}
		return false;
	}

	trc(1, "Copied firmware file \"" + file.fileName() + "\" to path: " + dirPath);

	newFile = QFileInfo(dirPath + "/" + file.fileName());

	switch(type)
	{
	case Resource::SoundResource:
		m_soundFiles = searchResourceFolders(_soundFilePath, QStringList() << "wav");
		break;
	case Resource::FimrwareResource:
		m_firmwareFile = searchResourceFolders(_firmwareFilePath, QStringList() << "rfe");
		break;
	case Resource::TestFimrwareResource:
		m_testFirmwareFile = searchResourceFolders(_testFirmwareFilePath, QStringList() << "rfe");
		break;
	case Resource::BootloaderResource:
		m_testFirmwareFile = searchResourceFolders(_bootloaderFilePath, QStringList() << "rfe");
		break;
	}

	return true;
}


void Resource::initInstance(QObject* parent)
{
	d = new Resource(parent);
	d->init();
}


void Resource::tryAddUrlToResource ( const QUrl& url, QString &result, uint &count, uint &successfull)
{
	count = successfull = 0;
	QFileInfo info(url.toLocalFile());

	if(!info.exists())
	{
		result = "The given data source does not exist.";
	}

	if(info.isFile())
	{
		count++;
		if(tryAddFileToResource(info, result))
			successfull++;
		return;
	}
	else if(info.isDir())
		searchFolderForFilesToAdd(info.absoluteFilePath(), 0, result, count, successfull);
}

void Resource::searchFolderForFilesToAdd(QString dirPath, uint level, QString& report, uint &count, uint &successfull)
{
	QDir dir(dirPath);

	QString spacer(level, QChar(' '));

	report += spacer + dirPath + "\n";

	if(!dir.exists())
		return;

	QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);

	foreach(QFileInfo info , entries)
	{
		if(info.isFile())
		{
			count++;

			QString tempError;
			if(tryAddFileToResource(info, tempError))
				successfull++;
			report += spacer + " - " + info.fileName() + " \n\t-> " + tempError + "\n";
		}
		else if(info.isDir())
		{
			searchFolderForFilesToAdd(info.absoluteFilePath(), level+1, report, count, successfull);
		}
	}
}

bool Resource::tryAddFileToResource ( const QFileInfo& fileInfo, QString& errMsg )
{
	bool result = false; 
	emit addFileRequest ( fileInfo, m_yesToAll, result, errMsg );

	if(result == false)
		return false;
 
	return true;
}



QFileInfoList Resource::searchResourceFolders ( QString dirPath, QStringList suffix )
{
	QDir dir(dirPath);
	QFileInfoList result;

	if(!dir.exists())
		return result;

	trc(2, "Searching for resource files at path: " + dir.absolutePath());

	QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files, QDir::Name);

	foreach(QFileInfo info , entries)
	{
		trc(5, " Investigating file " + info.fileName() );
		if(info.isFile())
		{
			if( suffix.contains(info.suffix()) )
				result << info;
		}
		else if(info.isDir())
		{
			result << searchResourceFolders(info.absoluteFilePath(), suffix);
		}
	}

	return result;
}
