/***************************************************************************
                Work Pool
                -----------------------------------------
	begin      : 2012/05/13
	copyright  : (C) 2011 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 3.1.0

    CopyRight(C) 2011 SolutionBox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#ifndef __WORK_POOL_H__
#define __WORK_POOL_H__

#include <semaphore.h>
# if __GNUC__ >= 3
#   include <ext/hash_map>
using namespace __gnu_cxx;
# else
#   include <hash_map>
# endif

typedef int (*work_notifyfn)(void *object, short success);

struct hash_key 
{
	size_t operator() (const string &k) const
	{
		return __stl_hash_string(k.c_str());
	}
};
struct compare_key
{
	bool operator () (const string s1, const string &s2) const
	{
		return s1 == s2;
	}
};

typedef hash_map<string, short, hash_key, compare_key> workurimap;

class work
{
public:
	work();
	~work();

	bool	init();
	bool	run(JOB_TYPE::JOB_TYPE type, string rundata, work_notifyfn nofi = NULL, void * parm = NULL);

	void	setexit(bool v);
	void	setenablesync(const char* szOn) {m_enablesync = szOn;}
	void	setnetworkmode(int mode) {m_networkmode = mode;}
	void	settargethost(vector<string>& targethost);
	
	pthread_t* getworkhandle() {return &m_thread;}

	const char*		getrundata() { return m_rundata.c_str(); }
	int				getsetp()	{ return m_step; }	
private:
	static void* working(void * pdata);

	int		RunWork(CSyncData &syncdata);
	int		validation(bool first, vector<string> &input, CSyncData &syncdata);
	int		synchronization(vector<string>& verified);

private:
	int					m_step;
	bool				m_exit;
	
	JOB_TYPE::JOB_TYPE	m_type;
	string				m_rundata;
	
	work_notifyfn		m_nofi;
	void*				m_parm;
	string				m_enablesync;
	int					m_networkmode;
	vector<string>		m_vectargethost;

	pthread_t			m_thread;
	pthread_cond_t		m_workcond;
	pthread_mutex_t		m_workmutex;

#ifdef _USE_POSIX_SEMAPHORES
	sem_t				*m_worksem;
#elif defined (_USE_POSIX_LOCK)
	int					m_workfd;
#endif // _USE_POSIX_SEMAPHORES
};

class workpool
{
public:
	enum WORK_SATAUSE
	{
		WORKING		= 0,
		NOTWORK		= 1
	};

public:
	static	void			init();
	static	workpool*		getInstance();
	static	void			release();

	int	CreatePool( int poolcnt = 10 );
	int DestroyPool();

	bool	addworkuri(vector<string>& syncdata, string &hash, int timeout = 5);
	bool	delworkuri(string key);

	void	printstatus(string prefixed = "");
	void	printstatusex(string prefixed = "");

	work*	GetWorkPool(int timeout = 0);
	void	ReleaseWork(work *w);

private:
	workpool();
	~workpool();

private:
	static workpool* m_inst;

	pthread_mutex_t			m_mutex;
	pthread_mutex_t			m_mutexuri;
	pthread_mutex_t			m_mutextry;

	workurimap				m_workurimap;
	
	map<work*, short> m_pool;	
};

#endif // __WORK_POOL_H__
