/***************************************************************************
                          cquerymanager.h  -  description
                             -------------------
    begin                : Sat Jun 8 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 CQUERYMANAGER_H
#define CQUERYMANAGER_H

/**
  *@author Mathias Küster
  *
  * This processes a queue of searches and sends the results,
  * the results come from CFileManager.
  */

#include <dclib/dcos.h>
#include <dclib/core/csocket.h>
#include <dclib/core/csingleton.h>
#include <dclib/core/ccallback.h>
#include <dclib/core/clist.h>
#include <dclib/dcobject.h>

#include <list>

class CQueryObject {
public:
	/** */
	CQueryObject()
	{
		pMessageSearch = 0;
	};
	/** */
	~CQueryObject()
	{
		delete pMessageSearch;
		pMessageSearch = 0;
	};

	/** */
	CString sHubName;
	/** */
	CString sHubHost;
	/** */
	CString sNick;
	/** */
	CMessageSearchFile * pMessageSearch;
	/** */
	time_t tTimeout;
};

class CQuerySendObject {
public:
	/** */
	CQuerySendObject() {
		m_pSocket = 0;
		m_pList   = new std::list<CString>();
		m_nPort   = 0;
	}
	/** */
	~CQuerySendObject() {
		delete m_pSocket;
		m_pSocket = 0;
		delete m_pList;
		m_pList = 0;
	}

	/** */
	CSocket * m_pSocket;
	/** */
	std::list<CString> * m_pList;
	/** */
	CString m_sSource;
	/** */
	int m_nPort;
};

class CMutex;
class CCaseFolder;

enum eSearchStat {
	essCOUNTACTIVE=0,
	essCOUNTPASSIVE,
	essCOUNTREJECT,
	essCOUNTERROR,
	essRESULTCOUNT,
	essRESULTCOUNTERROR
};

class CQueryManager : public CSingleton<CQueryManager> {
public:
	/** */
	CQueryManager();
	/** */
	virtual ~CQueryManager();

	/* */
	bool SearchQuery( CString hubname, CString hubhost, CString nick, CMessageSearchFile * msg );

	/** */
	ulonglong GetStat( enum eSearchStat e );
private:
	/** callbackfunction - called by CManager */
	int Callback();
	/** */
	void HandleQuery( CQueryObject * queryobject );
	/** */
	bool CheckSize( CQueryObject * queryobject, struct filebaseobject * fbo );
	/** */
	bool CheckType( CQueryObject * queryobject, struct filebaseobject * fbo );
	/** */
	bool AddResult( CQuerySendObject * querysendobject, CQueryObject * queryobject, 
		struct filebaseobject * fbo, CString filename, CString hash = CString() );
	/** */
	void SendResults();

	/** */
	_CCallback0 * m_pCallback;

	/**
	 * Mutex for query queue.
	 * Send list was never locked/unlocked.
	 */
	CMutex * m_pQueueMutex;
	/** the search queue */
	CList<CQueryObject> * m_pQueryQueue;
	/** */
	CList<CQuerySendObject> * m_pQuerySendList;

	/** */
	ulonglong m_nSearchCountActive;
	/** */
	ulonglong m_nSearchCountPassive;
	/** */
	ulonglong m_nSearchCountReject;
	/** */
	ulonglong m_nSearchCountError;
	/** */
	ulonglong m_nResultCount;
	/** */
	ulonglong m_nResultCountError;
	
	/** Avoid constant iconv_open / iconv_close */
	CCaseFolder * m_pCaseFolder;
};

#endif
