/***************************************************************************
 *	Copyright (C) 2005 by karye												*
 *	karye@users.sourceforge.net												*
 *																			*
 *	This program is free software; you can redistribute it and/or modify	*
 *	it under the terms of the GNU General Public License as published by	*
 *	the Free Software Foundation; either version 2 of the License, or		*
 *	(at your option) any later version.										*
 *																			*
 *	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.							*
 *																			*
 *	You should have received a copy of the GNU General Public License		*
 *	along with this program; if not, write to the							*
 *	Free Software Foundation, Inc.,											*
 *	59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.				*
 ***************************************************************************/

#include <QtCore/qglobal.h>  // for qWarning, qDebug, qCritical
#include <qdebug.h>          // for QDebug
#include <qdir.h>            // for QDir, operator|, QDir::Name, QDir::NoSym...
#include <qfile.h>           // for QFile
#include <qiodevice.h>       // for QIODevice, QIODevice::ReadOnly
#include <qlist.h>           // for QList<>::iterator, QList<>::Iterator, QList
#include <qlocale.h>         // for QLocale
#include <qstringlist.h>     // for QStringList, QStringListIterator
#include <qtextstream.h>     // for QTextStream

#include "common.h"          // for KurooDBSingleton, Info, SignalistSingleton
#include "global.h"          // for parsePackage
#include "portagedb.h"       // for KurooDB, DbConnection
#include "scanportagejob.h"
#include "settings.h"        // for KurooConfig
#include "signalist.h"       // for Signalist

namespace ThreadWeaver {
class Thread;
}  // namespace ThreadWeaver

/**
 * @class ScanPortageJob
 * @short Thread for scanning local portage tree for available packages.
 *
 * The packages are counted first, this to get a correct refresh progress in the gui.
 * Next portage cache in KurooConfig::dirEdbDep() is scanned for packages.
 * All packages are stored in table "package" in the database.
 */
ScanPortageJob::ScanPortageJob()
    : m_db( KurooDBSingleton::Instance()->getStaticDbConnection() )
{}

ScanPortageJob::~ScanPortageJob()
{
	KurooDBSingleton::Instance()->returnStaticDbConnection( m_db );

    /*if ( isAborted() )
        SignalistSingleton::Instance()->scanAborted();*/
}

/**
 * Scan Portage cache for packages in portage tree. Inserting found packages in db.
 * @return success
 */
void ScanPortageJob::run( ThreadWeaver::JobPointer /*self*/, ThreadWeaver::Thread*  /*thread*/)
{
	DEBUG_LINE_INFO;
	int count = 0;
	QDir dCategory, dPackage;
	dCategory.setFilter( QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot );
	dCategory.setSorting( QDir::Name );

	dPackage.setFilter( QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot );
	dPackage.setSorting( QDir::Name );

	if ( !m_db->isConnected() ) {
		qCritical() << "Scanning Portage. Can not connect to database";
        return;
	}

	SignalistSingleton::Instance()->scanPortageStarted();

	// Load Portage cache files to speed up portage scan
	loadCache();

	// Temporary table for all categories
	KurooDBSingleton::Instance()->singleQuery(	QStringLiteral("BEGIN TRANSACTION;"), m_db );
	KurooDBSingleton::Instance()->singleQuery(	QStringLiteral("CREATE TEMP TABLE category_temp ( "
	                                    		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
	                                    		"name VARCHAR(32) UNIQUE );")
	                                    		, m_db );

	KurooDBSingleton::Instance()->singleQuery(	QStringLiteral("CREATE TEMP TABLE subCategory_temp ( "
	                                    		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
	                                    		"name VARCHAR(32), "
	                                    		"idCategory INTEGER );")
	                                    		, m_db );

	// Temporary table for all packages
	KurooDBSingleton::Instance()->singleQuery(	QStringLiteral("CREATE TEMP TABLE package_temp ( "
	                                    		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
	                                    		"idCategory INTEGER, "
	                                          	"idSubCategory INTEGER, "
	                                          	"category VARCHAR(32), "
	                                          	"name VARCHAR(32), "
	                                          	"description VARCHAR(255), "
	                                          	"path VARCHAR(64), "
	                                          	"status INTEGER, "
	                                          	"meta VARCHAR(255), "
	                                          	"updateVersion VARCHAR(32) );")
	                                          	, m_db );

	// Temporary table for all versions
	KurooDBSingleton::Instance()->singleQuery(	QStringLiteral("CREATE TEMP TABLE version_temp ( "
	                                          	"id INTEGER PRIMARY KEY AUTOINCREMENT, "
	                                          	"idPackage INTEGER, "
	                                          	"name VARCHAR(32),"
	                                          	"description VARCHAR(255), "
	                                          	"homepage VARCHAR(128), "
	                                          	"licenses VARCHAR(64), "
	                                          	"useFlags VARCHAR(255),"
	                                          	"slot VARCHAR(32),"
	                                          	"size VARCHAR(32), "
	                                          	"status INTEGER, "
	                                          	"keywords VARCHAR(32) );")
	                                          	, m_db );

	//TODO: Again overlays support already built?
	// Gather all path = portage and overlays
	QStringList pathList;
	for ( const auto & path : KurooConfig::repoLocations() ) {
		if ( QFile::exists( path + QStringLiteral("/metadata/md5-cache/") ) ) {
			pathList << path + QStringLiteral("/metadata/md5-cache/");
		} else if ( QFile::exists( path ) ) {
			//WARN: this probly won't work because the code in scanInfo is expecting the md5-cache
			pathList << path;
		} else {
			qWarning() << LINE_INFO << path << "doesn't exist to read";
		}
	}

	// Scan Portage cache
	for (auto & itPath : pathList) {

		qDebug() << __PRETTY_FUNCTION__ << "Reading categories from" << itPath;
		//TODO: This is where I need to start removing deps on /var/cache/edb
		if ( !dCategory.cd( itPath ) ) {
			qWarning() << __PRETTY_FUNCTION__ << "Can not access" << itPath ;
			continue;
		}

		// Get list of categories in Portage
        int idCategory = 0;
		QString lastCategory;
		for (auto & itCategory : dCategory.entryList()) {

			//Filter out distfiles, eclass, licenses, metadata, packages, profiles, scripts
			if ( ! (itCategory.contains( u'-' ) || itCategory == QStringLiteral("virtual") ) )
				continue;

			qDebug() << __PRETTY_FUNCTION__ << "Reading category " << itCategory;
			QString category, subCategory;
			if ( itCategory == QStringLiteral("virtual") )
				category = itCategory;
			else {
				QStringList categoryParts = itCategory.split( u'-' );
				if ( categoryParts.size() == 2 ) {
					category = categoryParts[0];
					subCategory = categoryParts[1];
				} else {
					qWarning() << __PRETTY_FUNCTION__ << itCategory << "doesn't look like a valid category";
					continue;
				}
			}

			if ( lastCategory != category ) {
				idCategory = KurooDBSingleton::Instance()->insert( QStringLiteral(
					"INSERT INTO category_temp (name) VALUES ('%1');" ).arg( category ), m_db );
				lastCategory = category;
			}

			int idSubCategory = KurooDBSingleton::Instance()->insert( QStringLiteral(
				"INSERT INTO subCategory_temp (name, idCategory) VALUES ('%1', '%2');")
			.arg( subCategory, QString::number( idCategory ) ), m_db );

			if ( dPackage.cd( itPath + u'/' + itCategory) ) {
				qDebug() << __PRETTY_FUNCTION__ << "CD'ed into" << itPath << u'/' << itCategory;

				for (auto & itPackage : dPackage.entryList()) {

					// What is this MERGING?
					if ( itPackage == QStringLiteral("Manifest.gz") || itPackage.contains(QStringLiteral("MERGING")) )
						continue;

                    // Abort the scan
					if ( isAborted() ) {
						qWarning() << __PRETTY_FUNCTION__ << "Portage scan aborted";
						KurooDBSingleton::Instance()->singleQuery( QStringLiteral( "ROLLBACK TRANSACTION;" ), m_db );
						return;
					}

					qDebug() << __PRETTY_FUNCTION__ << "Reading package" << itPackage;
					QStringList parts = parsePackage( itPackage );
					if ( parts.isEmpty() ) {
						qWarning() << __PRETTY_FUNCTION__ << "can not match package" << itPackage;
						continue;
					}

					//parts[0] is category
					QString name = parts[1];
					QString version = parts[2];
					QString revision = parts[3];

					// Read the info from generated md5-cache, won't work for repos without the cache
					Info info( scanInfo( itPath, itCategory, name, version, revision ) );

					// Insert category and db id's in portage
					if ( !m_categories.contains( itCategory ) ) {
						m_categories[ itCategory ].idCategory = QString::number( idCategory );
						m_categories[ itCategory ].idSubCategory = QString::number( idSubCategory );
					}

					// Insert package in portage
					if ( !m_categories[ itCategory ].packages.contains( name ) ) {
						m_categories[ itCategory ].packages[ name ];
						m_categories[ itCategory ].packages[ name ].status = PACKAGE_AVAILABLE_STRING;
						m_categories[ itCategory ].packages[ name ].description = info.description;
						m_categories[ itCategory ].packages[ name ].path = itPath.section( QStringLiteral("/metadata/md5-cache"), 0, 0 );
						qDebug() << "Inserting package " << name << " into portage with path " << m_categories[itCategory].packages[name].path;
					}

					if ( revision != QStringLiteral( "r0" ) ) {
						version = QStringLiteral( "%1-%2" ).arg( version, revision );
					}
					// Insert version in portage
					if ( !m_categories[ itCategory ].packages[ name ].versions.contains( version ) ) {
						m_categories[ itCategory ].packages[ name ].versions[ version ].description = info.description;
						m_categories[ itCategory ].packages[ name ].versions[ version ].homepage = info.homepage;
						m_categories[ itCategory ].packages[ name ].versions[ version ].status = PACKAGE_AVAILABLE_STRING;
						m_categories[ itCategory ].packages[ name ].versions[ version ].licenses = info.licenses;
						m_categories[ itCategory ].packages[ name ].versions[ version ].useFlags = info.useFlags;
						m_categories[ itCategory ].packages[ name ].versions[ version ].slot = info.slot;
						m_categories[ itCategory ].packages[ name ].versions[ version ].size = info.size;
						m_categories[ itCategory ].packages[ name ].versions[ version ].keywords = info.keywords;
					}

					// Post scan count progress
					if ( ( ++count % 100 ) == 0 )
						setProgress( count );
				}
			}
			else
				qWarning() << "Scanning Portage. Can not access " << itPath << itCategory;

			SignalistSingleton::Instance()->scanProgress(++count);
		}
	}

	// Now scan installed packages, eg mark packages as installed and add "old" packages (not in Portage anymore)
	scanInstalledPackages();

	// Iterate through portage map and insert everything in db
	PortageCategories::iterator itCategoryEnd = m_categories.end();
	for ( PortageCategories::iterator itCategory = m_categories.begin(); itCategory != itCategoryEnd; ++itCategory ) {

		PortagePackages::iterator itPackageEnd = itCategory.value().packages.end();
		for ( PortagePackages::iterator itPackage = itCategory.value().packages.begin(); itPackage != itPackageEnd; ++itPackage ) {

			QString idPackage;
			QString idCategory = itCategory.value().idCategory;
			QString idSubCategory = itCategory.value().idSubCategory;

			QString category = itCategory.key();
			QString package = itPackage.key();
			QString status = itPackage.value().status;
			QString description = itPackage.value().description;
			QString path = itPackage.value().path;

			// Create meta tag containing all text of interest for searching
			QString meta = category + u' ' + package + u' ' + description;

			QString sql = QStringLiteral( "INSERT INTO package_temp (idCategory, idSubCategory, category, "
			                       "name, description, status, path, meta) "
			                       "VALUES ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8');")
				.arg( idCategory, idSubCategory, category, package,
				description, status, path, meta );

			idPackage = QString::number( KurooDBSingleton::Instance()->insert( sql, m_db ) );

			PortageVersions::iterator itVersionEnd = itPackage.value().versions.end();
			for ( PortageVersions::iterator itVersion = itPackage.value().versions.begin(); itVersion != itVersionEnd; ++itVersion ) {

				QString version = itVersion.key();
				description = itVersion.value().description;
				QString homepage = itVersion.value().homepage;
				QString status = itVersion.value().status;
				QString licenses = itVersion.value().licenses;
				QString useFlags = itVersion.value().useFlags;
				QString slot = itVersion.value().slot;
				QString size = itVersion.value().size;
				QString keywords = itVersion.value().keywords;

				QString sqlVersion = QStringLiteral( "INSERT INTO version_temp "
				                              "(idPackage, name, description, homepage, size, keywords, status, licenses, useFlags, slot) "
				                              "VALUES ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', " )
					.arg( idPackage, version, description, homepage, size,
					keywords, status, licenses, useFlags );

				sqlVersion += QStringLiteral( "'%1');" ).arg( slot );
				KurooDBSingleton::Instance()->insert( sqlVersion, m_db );
			}
		}
	}
	m_categories.clear();

	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("COMMIT TRANSACTION;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("UPDATE dbInfo SET data = '%1' WHERE meta = 'packageCount';").arg( count ), m_db );

	// Move content from temporary table
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DELETE FROM category;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DELETE FROM subCategory;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DELETE FROM package;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DELETE FROM version;"), m_db );

	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("BEGIN TRANSACTION;"), m_db );
	KurooDBSingleton::Instance()->insert( QStringLiteral("INSERT INTO category SELECT * FROM category_temp;"), m_db );
	KurooDBSingleton::Instance()->insert( QStringLiteral("INSERT INTO subCategory SELECT * FROM subCategory_temp;"), m_db );
	KurooDBSingleton::Instance()->insert( QStringLiteral("INSERT INTO package SELECT * FROM package_temp;"), m_db );
	KurooDBSingleton::Instance()->insert( QStringLiteral("INSERT INTO version SELECT * FROM version_temp;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("COMMIT TRANSACTION;"), m_db );

	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DROP TABLE category_temp;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DROP TABLE subCategory_temp;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DROP TABLE package_temp;"), m_db );
	KurooDBSingleton::Instance()->singleQuery( QStringLiteral("DROP TABLE version_temp;"), m_db );

    /*setStatus( "ScanPortage", i18n("Done.") );
    setProgressTotalSteps( 0 );*/

	SignalistSingleton::Instance()->scanPortageComplete();
}

/**
 * Collect list of installed packages.
 */
void ScanPortageJob::scanInstalledPackages()
{
	QDir dCategory, dPackage;
	dCategory.setFilter( QDir::Dirs | QDir::NoSymLinks );
	dCategory.setSorting( QDir::Name );

	if ( !dCategory.cd( KurooConfig::dirDbPkg() ) )
		qWarning() << "Scanning installed packages. Can not access " << KurooConfig::dirDbPkg();

    //setStatus( "ScanInstalled", i18n("Collecting installed packages...") );

	// Get list of categories for installed packages
	QStringList categoryList = dCategory.entryList();
	QStringList::Iterator itCategoryEnd = categoryList.end();
	for ( QStringList::Iterator itCategory = categoryList.begin(); itCategory != itCategoryEnd; ++itCategory ) {

		if ( *itCategory == u'.' || *itCategory == QStringLiteral("..") )
			continue;

		// Get list of packages in this category
		dPackage.setFilter( QDir::Dirs | QDir::NoSymLinks );
		dPackage.setSorting( QDir::Name );

		if ( dPackage.cd( KurooConfig::dirDbPkg() + u'/' + *itCategory ) ) {
			QStringList packageList = dPackage.entryList();
			QStringList::Iterator itPackageEnd = packageList.end();
			for ( QStringList::Iterator itPackage = packageList.begin(); itPackage != itPackageEnd; ++itPackage ) {

				if ( *itPackage == u'.' || *itPackage == QStringLiteral("..") || ( *itPackage ).contains(QStringLiteral("MERGING")) )
					continue;

                QStringList parts = parsePackage( *itPackage );
				if ( !parts.isEmpty() ) {
					QString name = parts[1];
					QString version;
					if ( parts[3] == QStringLiteral( "r0" ) ) {
						version = parts[2];
					} else {
						version = QStringLiteral( "%1-%2" ).arg( parts[2], parts[3] );
					}

					// Insert category if not found in portage
					if ( !m_categories.contains( *itCategory ) )
						m_categories[ *itCategory ];

					// Insert and/or mark package as installed (old is package not in portage anymore)
					if ( !m_categories[ *itCategory ].packages.contains( name ) ) {
						m_categories[ *itCategory ].packages[ name ];
						m_categories[ *itCategory ].packages[ name ].status = PACKAGE_OLD_STRING;
					}
					else
						m_categories[ *itCategory ].packages[ name ].status = PACKAGE_INSTALLED_STRING;

					// Insert old version in portage
					if ( !m_categories[ *itCategory ].packages[ name ].versions.contains( version ) )
						m_categories[ *itCategory ].packages[ name ].versions[ version ];

					// Mark version as installed
					m_categories[ *itCategory ].packages[ name ].versions[ version ].status = PACKAGE_INSTALLED_STRING;

				}
				else
					qWarning() << "Scanning installed packages. Can not match " << *itPackage;
			}
		}
		else
			qWarning() << "Scanning installed packages. Can not access " << KurooConfig::dirDbPkg() << "/" << *itCategory;
	}
    //setStatus( "ScanInstalled", i18n("Done.") );
}

/**
 * Collect info about this ebuild. Based on Jakob Petsovits code.
 * @param path		base path to portage directory (like /usr/portage/metadata/md5-cache)
 * @param category	category name (like app-portage)
 * @param name		package name (like kuroo)
 * @param version
 * @return  false if the file can't be opened, true otherwise.
 */
auto ScanPortageJob::scanInfo( const QString& path, const QString& category, const QString& name, const QString& version, const QString& revision ) -> Info
{
//WARN: This won't work for anything but /usr/portage for now!
	Info info;
	QFile file( path + u'/' + category + u'/' + name + u'-' + version + (revision == QStringLiteral("r0") ? QString() : (u'-' + revision)) );

	if ( !file.open( QIODevice::ReadOnly ) ) {
		qWarning() << __PRETTY_FUNCTION__ << "Failed reading" << path << "/" << category << "/" << name << "-" << version << u'-' << revision;

		info.slot = u'0';
		info.homepage = u'0';
		info.licenses = u'0';
		info.description = u'0';
		info.keywords = u'0';
		info.useFlags = u'0';
		info.size = u'0';
		return info;
	}

	QString line;
	QTextStream stream( &file );

	// Check portage version and read out the package info strings
// 	if ( KurooConfig::portageVersion21() ) {
//
		// We are on portage version post 2.1
		while ( !stream.atEnd() ) {
			line = stream.readLine();

			if ( line.startsWith( QStringLiteral("LICENSE=") ) )
				info.licenses = line.section(QStringLiteral("LICENSE="), 1, 1).replace(u'\'', QStringLiteral("''")).replace(u'%', QStringLiteral("&#37;"));
			else
				if ( line.startsWith( QStringLiteral("KEYWORDS=") ) )
					info.keywords = line.section(QStringLiteral("KEYWORDS="), 1, 1);
				else
					if ( line.startsWith( QStringLiteral("SLOT=") ) )
						info.slot = line.section(QStringLiteral("SLOT="), 1, 1);
					else
						if ( line.startsWith( QStringLiteral("DESCRIPTION=") ) )
							info.description = line.section(QStringLiteral("DESCRIPTION="), 1, 1).replace(u'\'', QStringLiteral("''")).replace(u'%', QStringLiteral("&#37;"));
						else
							if ( line.startsWith( QStringLiteral("IUSE=") ) )
								info.useFlags = line.section(QStringLiteral("IUSE="), 1, 1);
							else
								if ( line.startsWith( QStringLiteral("HOMEPAGE=") ) )
									//TODO: handle multiple homepages
									info.homepage = line.section(QStringLiteral("HOMEPAGE="), 1, 1).replace(u'\'', QStringLiteral("''")).replace(u'%', QStringLiteral("&#37;"));
		}
//	}
//	else {
	//int lineNumber(0);
//WARN: Portage seems to have down-graded to the older style flat cache file for the cache in the repository (/usr/portage).  Other caches (layman) may behave differently
		// We are on portage version pre 2.1
// 		while ( !stream.atEnd() ) {
// 			line = stream.readLine();
// 			lineNumber++;
//
// 			// each line has a fixed meaning, as it seems.
// 			// so iterate through the lines.
// 			switch( lineNumber ) {
// 				case 1: // compile? dependency stuff
// 					break;
// 				case 2: // runtime? dependency stuff
// 					break;
// 				case 3: // the package slot
// 					info.slot = line;
// 					break;
// 				case 4: // file location, starting with mirror://
// 					break;
// 				case 5: // empty?
// 					break;
// 				case 6: // DirHome page
// 					info.homepage = line.replace('\'', "''").replace('%', "&#37;");
// 					break;
// 				case 7: // licenses
// 					info.licenses = line.replace('\'', "''").replace('%', "&#37;");
// 					break;
// 				case 8: // description
// 					info.description = line.replace('\'', "''").replace('%', "&#37;");
// 					break;
// 				case 9: // keywords
// 					info.keywords = line;
// 					break;
// 				case 10: // inherited eclasses?
// 					break;
// 				case 11: // useFlags
// 					info.useFlags = line;
// 					break;
// 				default:
// 					break;
// 			}
// 		}
//	}
	file.close();
/*
//TODO: This is too difficult at the moment, since the change to Manifest2 format in GLEP 44, we don't have files/digest-* files
//to read.  The data that we need is in the Manifest2 file, but the lines no longer say the ebuild/version number, instead
//it has a file name, so we would have to parse the ebuid to find out what lines to read from the Manifest2 file.
	// Get package size. Try in cache first.
	QString size = cacheFind( category + "/" + name + "-" + version ) ;
	if ( !size.isEmpty() ) {
		info.size = formatSize( size );
	} else {
		QString path = KurooConfig::dirPortage() + "/" + category + "/" + name + "/files/digest-" + name + "-" + version;
		file.setName( path );
		if ( file.open( QIODevice::ReadOnly ) ) {
			std::ifstream in( path );
			std::string word;
			while ( in >> word );
			file.close();
			info.size = formatSize( word );

			// Add new value into cache.
			KurooDBSingleton::Instance()->insert( QString("INSERT INTO cache (package, size) VALUES ('%1', %2);")
			                                      .arg( name + "-" + version ).arg( word ), m_db );
		}
		else
			qCritical() << "Scanning installed packages. Reading: " << path;
	}
*/

	return info;
}

/**
 * Format package size nicely
 * @fixme: Check out KIO_EXPORT QString KIO::convertSize
 * @param size
 * @return total		as "xxx kB"
 */
auto ScanPortageJob::formatSize( const QString& size ) -> QString
{
	QString total;

	uint num = size.toUInt();
	if ( num < 1024 )
		total = QStringLiteral("1 kB ");
	else
		total = QLocale::system().formattedDataSize(num);

	return total;
}

/**
 * Load m_mapCache with items from DB.
 */
void ScanPortageJob::loadCache()
{
	m_mapCache.clear();
	const QStringList cacheList = KurooDBSingleton::Instance()->query( QStringLiteral("SELECT package, size FROM cache ;"), m_db );
	QStringListIterator it( cacheList );
	while( it.hasNext() ) {
		QString package = it.next();
		QString size = it.next();
		m_mapCache.insert( package, size );
	}
}

/**
 * Find cached size for package.
 * @param packages
 * @return size or NULL if na
 */
// QString ScanPortageJob::cacheFind( const QString& package )
// {
// 	QMap<QString, QString>::iterator it = m_mapCache.find( package ) ;
// 	if ( it != m_mapCache.end() )
//         return it.value();
// 	else
// 		return QString();
// }
