/***************************************************************************
                           cfilemanager.h  -  description
                             -------------------
    begin                : Sat Aug 03 2002
    copyright            : (C) 2002-2004 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef CFILEMANAGER_H
#define CFILEMANAGER_H

/**
  *@author Mathias Küster
  *
  * This handles the files in the share and the filelist, much of which
  * is handled by the CSearchIndex and CShareList classes.
  *
  * This handles putting data into CSearchIndex. Looking for files
  * by TTH is done in CSearchIndex but keyword searches are now
  * handled here.
  */

#include <dclib/dcos.h>
#include <dclib/core/types.h>
#include <dclib/core/cthread.h>
#include <dclib/core/csingleton.h>
#include <dclib/core/cstring.h>
#include <dclib/core/clist.h>

#include <dclib/dclib-stl-use.h>

#include <set>
#include <list>

#if ( (DCLIB_USES_UNORDERED_SET == 1) && (DCLIB_ALLOWS_CSTRING_KEY == 1) )

#include <algorithm>
#include <unordered_set>
#include <dclib/core/cstringhash.h>
typedef std::unordered_set<CString> FileNameSet;

#elif ( (DCLIB_USES_TR1_UNORDERED_SET == 1) && (DCLIB_ALLOWS_CSTRING_KEY == 1) )

#include <algorithm>
#include <tr1/unordered_set>
#include <dclib/core/cstringhash.h>
typedef std::tr1::unordered_set<CString> FileNameSet;

#else

typedef std::set<CString> FileNameSet;

#endif

#include <map>
typedef std::map<CString, eFileTypes> FileTypeMap;

class CFileManagerInfo;
class CByteArray;
class CSearchIndex;
class CShareList;
class DCConfigShareFolder;
class _CCallback0;

class CFileManager : public CSingleton<CFileManager>, public CThread {

public:
	/** */
	CFileManager();
	/** */
	virtual ~CFileManager();

	/** */
	ulonglong GetShareSize();
	/** */
	unsigned long GetShareBufferSize( eShareBufferType type );
	/** */
	int GetShareBuffer( eShareBufferType type, CByteArray * sharebuffer, bool decompress = false );
	/**
	 * Gets a partial XML list, use depth = -1 for all,
	 */
	void GetPartialListing( const CString & dir, CString & result, int depth = 0 );

	/** Search with any size any type */
	std::set<unsigned long> * Search( unsigned int maxresults, std::list<CString> * words );
	/** Search with any size of specified type */
	std::set<unsigned long> * Search( unsigned int maxresults, std::list<CString> * words, eFileTypes type );
	/** Search for at least size any type */
	std::set<unsigned long> * SearchAtLeast( unsigned int maxresults, std::list<CString> * words, ulonglong size );
	/** Search for at least size of specified type */
	std::set<unsigned long> * SearchAtLeast( unsigned int maxresults, std::list<CString> * words, ulonglong size, eFileTypes type );
	/** Search for at most size any type */
	std::set<unsigned long> * SearchAtMost( unsigned int maxresults, std::list<CString> * words, ulonglong size );
	/** Search for at most size of specified type */
	std::set<unsigned long> * SearchAtMost( unsigned int maxresults, std::list<CString> * words, ulonglong size, eFileTypes type );
	/** */
	std::set<unsigned long> * SearchHash( CString s );
	/** */
	bool GetFileBaseObject( unsigned long index, struct filebaseobject * fbo, CString & filename );
	/** */
	CString GetHash( unsigned long hbi );
	/** Get the TTH leaves for the given TTH */
	CByteArray * GetHashLeaves( CString tth );
	
	/** */
	bool CreateShareList();
	/** */
	bool CreateHashList();
	/** */
	void CreateSearchIndex();
	/** called on /rebuild command */
	bool RebuildLists();
	/** called to start hash leaf data verification */
	bool ValidateLeaves();

	/** */
	ulonglong CalcShareSize();

	/** thread callbackfunction */
	virtual void Thread();
	
	/** */
	CString GetFileName( unsigned long fboid );
	/** Returns true if a filelist refresh is in progress, otherwise returns false. */
	bool IsCreateShareListRunning();
	
	/** return the filetype */
	eFileTypes GetFileType( CString file );
	
private:
	/** */
	void ThreadCreateSearchIndex();
	/** */
	void ThreadCreateHashList();
	/** */
	void ThreadCreateShareList();
	/** */
	void ThreadCreateShareList( int depth, CString curr, CString relpath, double percent );
	/** /rebuild lists */
	void ThreadRebuildLists();
	/** */
	void ThreadValidateLeaves();

	/** Called by CManager (via the callback) */
	int FileManagerCallback();

	/** */
	ulonglong CalcShareSize( int depth, CString base, CString curr, CString relpath );
	/** */
	void InitFileTypeList();

	/** */
	FileNameSet * m_pFileNameSet;
	/** */
	FileTypeMap m_FileTypeMap;

	/** */
	CList<DCConfigShareFolder> m_SharedFolders;
	/** */
	DCConfigShareFolder * m_pShareFolder;
	/** */
	unsigned long m_nFileBaseIndex;
	/** */
	CString m_sShareIndexBuffer;

	/** */
	time_t m_tCreateShareListTimeout;

	/** */
	CFileManagerInfo * m_pFileManagerInfo;
	/** */
	_CCallback0 * m_pFileManagerCallback;

	/** search index class */
	CSearchIndex * m_pSearchIndex;
	/** sharelist class */
	CShareList * m_pShareList;
	/** */
	CByteArray * m_pHashMemory;
};

#endif
