#ifndef _DISPATCHER_
#define _DISPATCHER_

#include "sys/sys"
#include "memory/memory"

#include "balancer/balancer"
#include "config/config"
#include "ThreadsAndMutexes/thread/thread"
#include "ThreadsAndMutexes/threadlist/threadlist"
#include "backendvector/backendvector"
#include "netbuffer/netbuffer"

// Dispatching algorithm workers
#include "DispatchAlgorithms/algorithm/algorithm"
#include "DispatchAlgorithms/roundrobin/roundrobin"
#include "DispatchAlgorithms/firstactive/firstactive"
#include "DispatchAlgorithms/leastconn/leastconn"
#include "DispatchAlgorithms/external/external"
#include "DispatchAlgorithms/hashedip/hashedip"
#include "DispatchAlgorithms/storedip/storedip"
#include "DispatchAlgorithms/weightedload/weightedload"

#ifdef MEMDEBUG
class Dispatcher: public Thread, public Memory
#else    
class Dispatcher: public Thread
#endif
{
public:

    Dispatcher(int fd, struct in_addr ip);
    Dispatcher(int fd);
    virtual ~Dispatcher();

    virtual void execute()  = 0;
    virtual void dispatch() = 0;
    virtual void handle()   = 0;

    bool check_dos();
    bool check_acl();

    int targetbackend() const 			{ return target_backend; }
    void targetbackend(int t)			{ target_backend = t; }
    struct in_addr clientip() const 		{ return client_ip; }
    void clientip(struct in_addr i)		{ client_ip = i;
	                                          clientip_str = ""; }
    string const &clientipstr();
    int clientfd() const 			{ return client_fd; }
    void clientfd(int c)			{ client_fd = c; }
    int backendfd() const 			{ return backend_fd; }
    void backendfd(int b)			{ backend_fd = b; }
    Algorithm *algorithm() const		{ return algo; }
    
    BackendVector &targetlist()		 	{ return target_list; }
    void targetlist (BackendVector t)		{ target_list = t; }

private:
    void start_dispatcher();
    struct in_addr client_ip;
    int target_backend, client_fd, backend_fd;
    Algorithm *algo;
    BackendVector target_list;
    string clientip_str;
};

#endif
