#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"
#include "SocketHandling/socket/socket"

// 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(Socket &s);
    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; }
    
    Socket &clientfd()	 			{ return client_fd; }
    void clientfd(Socket &c)			{ client_fd = c; }

    Socket &backendfd()	 			{ return backend_fd; }
    void backendfd(Socket &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();
    
    int target_backend;
    Socket client_fd, backend_fd;
    Algorithm *algo;
    BackendVector target_list;
};

#endif
