#include "kclucenedaemon.h"

KCLuceneDaemon::KCLuceneDaemon ()
{
	m_indexMultiSearchersList.setAutoDelete(TRUE);
	m_indexSingleSearchersList.setAutoDelete(TRUE);
}

KCLuceneDaemon::~KCLuceneDaemon ()
{
	m_indexMultiSearchersList.clear();
	m_indexSingleSearchersList.clear();
}

void KCLuceneDaemon::deleteSearchers (QStringList &indexesPathList, QString *res)
{

	//TODO DELETING SEARCHERS
	//searchers are closed and deleted as soon as no one needs them.

	//increment indexList counters indexesPathList
	for ( QStringList::Iterator it = indexesPathList.begin(); it != indexesPathList.end(); ++it )
	{
		//conditional test here but it MUST exist
		QMap<QString, int>::Iterator it2 = m_indexSingleSearchersListCounter.find(*it);
		if (it2 != m_indexSingleSearchersListCounter.end() ) 
		{
			kdDebug() << "KCLuceneDaemon::customEvent" << it2.data() << endl;
			it2.data() = it2.data() -1;
			kdDebug() << "KCLuceneDaemon::customEvent B" << it2.data() << endl;
			if (it2.data() == 0)
			{
				kdDebug() << "KCLuceneDaemon::customEventDELETE SINGLE" << it2.data() << endl;
				//fixme. I could get the index value from m_indexSingleSearchersListCounter
				lucene::search::IndexSearcher * idS = m_indexSingleSearchersList.find(*it);
				idS->close();
				kdDebug() << "KCLuceneDaemon::customEventDELETE SINGLE CLOSED" << it2.data() << endl;

// 				delete idS;
				kdDebug() << "KCLuceneDaemon::customEventDELETE SINGLE DELETED" << it2.data() << endl;

				m_indexSingleSearchersList.remove(*it);
				kdDebug() << "KCLuceneDaemon::customEvent BDELETE SINGLE REMOVED"  << endl;
			}
		}
	}
	
	//increment multiIndexList counters indexesPathList
	const QString indexKey = indexesPathList.join("-");
	QMap<QString, int>::Iterator it2 = m_indexMultiSearchersListCounter.find(indexKey); 	
	if ( it2 !=  m_indexMultiSearchersListCounter.end())
	{
		kdDebug() << "KCLuceneDaemon::customEvent" << it2.data() << endl;
		it2.data() = it2.data() -1;
		kdDebug() << "KCLuceneDaemon::customEvent" << it2.data() << endl;
		if (it2.data() == 0)
		{
			kdDebug() << "KCLuceneDaemon::customEvent DELETE MULTI" << it2.data() << endl;
			m_indexMultiSearchersList.remove(indexKey);
			kdDebug() << "KCLuceneDaemon::customEvent DELETE MULTI FINISHED" << endl;

		}
	}
}

bool KCLuceneDaemon::initCLuceneIndexes (QStringList &indexesPathList)
{
	// sort list of indexes
	//first look if list already is in use then if not check if it is valid.
	//if (IndexVal)
	QStringList subList;
	bool receivedListIsGood =  initIndexes(indexesPathList);
	bool subListIsGood = FALSE;
	if (! receivedListIsGood)
	{
		kdDebug() << "KCLuceneDaemon::initCLuceneIndexes() DAEMON BAD INDEX FILES TRYING TO GET SUBSPACE" << endl;
		subList = getValidSubList(indexesPathList);
		subListIsGood = initIndexes(subList);
	}
	//try to use some of the given indexes
	if ( (!receivedListIsGood) && (! subListIsGood) )
	{
		kdDebug() << "KCLuceneDaemon::initCLuceneIndexes() NO SUBSPACE FOUND " << endl;
		return false;
	}
	else if ( (!receivedListIsGood) && (subListIsGood) )
	{
		kdDebug() << "KCLuceneDaemon::initCLuceneIndexes() SUBSPACE FOUND " << endl;
		indexesPathList = subList;
	}
	kdDebug() << "KCLuceneDaemon::initCLuceneIndexes() indexes should exist: receivedListIsGood : " << receivedListIsGood << endl;

	return true;
	
}

QStringList KCLuceneDaemon::getValidSubList(QStringList indexesPathList)
{
	QStringList newList;
	for ( QStringList::Iterator it = indexesPathList.begin(); it != indexesPathList.end(); ++it )
	{
		
		kdDebug() <<  "DAEMON: INDEXLISTITEM " << *it <<endl;
		//const char* str = (*it).latin1();//FIXME:
		char* p_str = (char*) (const char*) (*it).latin1();
		if (lucene::index::IndexReader::indexExists( p_str ) ) //str directory path to the index
		{
			newList.append(*it);
		}
	}
	return newList;
	

}

int KCLuceneDaemon::initIndexes(QStringList indexesPathList)
{
	//sort PathList
	indexesPathList.sort();
	
	//check the whole list is already registered as such
	//if single Index check on ItemList
	if ( indexesPathList.count()==1 )
	{
		kdDebug() << "DAEMON: INIT SINGLE INDEX STARTED" << endl;
		//sset a bool constant to Single ???
		if (! initSingleIndex( indexesPathList ))
			return 0;
		else
			return 1;
	}
	else
	{
		kdDebug() <<  "DAEMON: MULTI-INDEX STARTED" << endl;
		if (! initMultiIndex(indexesPathList) ) 
			return 0;
		else
			return 1;
	}
	
}

int KCLuceneDaemon::initSingleIndex( QStringList indexesPathList )
{
	//should only one single item
	if ( m_indexSingleSearchersList.find( *(indexesPathList.begin())) )
	{
		kdDebug() << "DAEMON: INIT SINGLE-INDEXE: INDEX ALRERADY registered" << endl;
		return 1;
	}
	else if ( ! isIndexesPathListValid(indexesPathList) )
	{
		kdDebug() << "DAEMON: INIT MULTIINDEXEXES: NEW INDEX LIST IS NOT VALID" << endl;
		kdDebug() <<"DAEMON: INIT MULTIINDEXEXES: TRY TO GET SOME" << endl;
		
		return  0;
	}
	else
	{
		kdDebug() << "DAEMON: SINGLE INIT INDEX: NEW INDEX LIST IS VALID. GOOD" << endl;
		
		InitAllSingleSearchers(indexesPathList);
		//dann init MultiSearch
		return  1;

	}

}

int KCLuceneDaemon::initMultiIndex( QStringList  indexesPathList)
{
	QString indexKey = indexesPathList.join("-");
	if (m_indexMultiSearchersList.find(indexKey) )
	{
		kdDebug() << "KCLuceneDaemon::initMultiIndex()DAEMON: INIT MULTI-INDEXEXES: INDEX ALRERADY registered" << endl; 
		//don't increment multiIndexCounter here because 
		//it is not sure that the query is accepted
		//do it when a newQuery starts
		
		//FIXME : what should I return ? 1 is SUCCESS.
		return 1;
	}
	else if ( ! isIndexesPathListValid(indexesPathList) )
	{
		kdDebug() << "KCLuceneDaemon::initMultiIndex() DAEMON: INIT MULTIINDEXEXES: NEW INDEX LIST IS NOT VALID" << endl; 
		return  0;
	}
	else
	{
		kdDebug() << "KCLuceneDaemon::initMultiIndex() DAEMON: MULTIINIT INDEXEXES: NEW INDEX LIST IS VALID. GOOD" << endl; 
		// register each item first
		
		InitAllSingleSearchers(indexesPathList);
		InitAllMultiSearchers(indexesPathList);
		return  1;
	}

}

// not thread, should be called while holding a mutex
void KCLuceneDaemon::prepareIndexForQuery (QStringList &indexesPathList)
{
	//increment indexList counters indexesPathList
	
	kdDebug() << "KCLuceneDaemon::startQuery after querylist......" << indexesPathList.count() << endl;

	for ( QStringList::Iterator it = indexesPathList.begin(); it != indexesPathList.end(); ++it )
	{
		kdDebug() << "KCLuceneDaemon::startQuery *it    : " << endl;

		kdDebug() << "KCLuceneDaemon::startQuery *it    : " << *it << endl;

		//conditional test here but it MUST exist
		QMap<QString, int>::Iterator it2 = m_indexSingleSearchersListCounter.find(*it);
		if (it2 != m_indexSingleSearchersListCounter.end() ) 
		{
			kdDebug() << "KCLuceneDaemon::startQueryA" << it2.data() << endl;
			it2.data() = it2.data() +1;
			kdDebug() << "KCLuceneDaemon::startQueryB" << it2.data() << endl;
		}
	}
	
	kdDebug() << "KCLuceneDaemon::startQuery after AB    : " << endl;

	//increment multiIndexList counters indexesPathList
	const QString indexKey = indexesPathList.join("-");
	QMap<QString, int>::Iterator it2 = m_indexMultiSearchersListCounter.find(indexKey); 	
	if ( it2 !=  m_indexMultiSearchersListCounter.end())
	{
		kdDebug() << "KCLuceneDaemon::startQueryA" << it2.data() << endl;
		it2.data() = it2.data() +1;
		kdDebug() << "KCLuceneDaemon::startQueryB" << it2.data() << endl;
	}
}

bool KCLuceneDaemon::isIndexesPathListValid(QStringList indexesPathList)
{
	for ( QStringList::Iterator it = indexesPathList.begin(); it != indexesPathList.end(); ++it )
	{
		
		kdDebug() <<  "DAEMON: INDEXLISTITEM " << *it <<endl;
		//const char* str = (*it).latin1();//FIXME:
		char* p_str = (char*) (const char*) (*it).latin1();
		if (! lucene::index::IndexReader::indexExists( p_str ) ) //str directory path to the index
		{
			kdDebug() <<  "DAEMON: INDEXLISTITEM " << *it << "DOES NOT EXIST"<< endl;
			return FALSE;
		}
		
		//static FSDirectory& getDirectory(const TCHAR* file, const bool create); return Directory
		
		
	}
	return TRUE;
}


bool KCLuceneDaemon::InitAllSingleSearchers(QStringList & indexesPathList)
{
	for ( QStringList::Iterator it = indexesPathList.begin(); it != indexesPathList.end(); ++it )
	{
		if (!  m_indexSingleSearchersList.find(*it) ) 
		{
			kdDebug() <<  "DAEMON: INDEXLISTITEM " << *it << "DOES NOT EXIST"<<endl;
			char* p_str = (char*) (const char*) (*it).latin1(); //FIXME:
			//init IndexReader Thread Safe
			m_indexSingleSearchersList.insert( *it , new lucene::search::IndexSearcher(p_str ) );
			//init counter	
			m_indexSingleSearchersListCounter.insert( *it ,0 );
		}
		
	}
	return TRUE;
}

bool KCLuceneDaemon::InitAllMultiSearchers(QStringList & indexesPathList)
{
	const QString indexKey = indexesPathList.join("-");
	if (m_indexMultiSearchersList.find(indexKey))
	{
		kdDebug() <<"DAEMON: MULTIINDEX   ALREADY REGISTERED" << endl;
		return TRUE;
	}
	else
	{
		kdDebug() << "DAEMON: MULTIINDEX   NOW BEING REGISTERED\n" << endl;
		m_indexMultiSearchersList.insert(indexKey , new QStringList(indexesPathList) );
		//multiSearch array will be build on thread creation
		m_indexMultiSearchersListCounter.insert(indexKey , 0);
		kdDebug() << "DAEMON: MULTIINDEX   NOW  REGISTERED" << endl;

	}
		return TRUE;
}

bool KCLuceneDaemon::isIndexesListValid(QStringList & /*indexesPathList*/)
{
	return TRUE;
}

