#ifndef _BACKEND_
#define _BACKEND_

#include "sys/sys"
#include "backenddef/backenddef"
#include "fdset/fdset"
#include "error/error"
#include "ThreadsAndMutexes/mutex/mutex"
#include "profiler/profiler"
#include "backendcheck/backendcheck"
#include "httpbuffer/httpbuffer"
#include "dnsentry/dnsentry"

using namespace std;

class Backend {
public:
    Backend ();
    Backend (BackendDef const &b);
    virtual ~Backend();
    bool connect();
    void markconnecterror();
    
    int sock() const 			{ return clsocket; }
    
    void check();
    string description() const;
    
    bool available() const;
    string availablestr() const;
    
    bool live() const			{ return islive; };
    void live (bool state);    
    string livestr() const;
    
    void up (bool state);
    bool up() const			{ return isup; }
    string upstr() const;
    
    string const &server() const 	{ return bdef.server(); }
    void server(string s)		{ bdef.server(s); }

    int port() const 			{ return bdef.port(); }
    void port(int p)			{ bdef.port(p); }

    unsigned maxconn() const 		{ return bdef.maxconn(); }
    void maxconn (unsigned m)		{ bdef.maxconn(m); }

    string const &hostmatch() const	{ return bdef.hostmatch(); }
    void hostmatch(string const &s)	{ bdef.hostmatch(s); }
    regex_t const &hostregex() const	{ return bdef.hostregex(); }

    string const &urlmatch() const	{ return bdef.urlmatch(); }
    void urlmatch(string const &u)	{ bdef.urlmatch(u); }
    regex_t const &urlregex() const	{ return bdef.urlregex(); }

    unsigned weight() const		{ return bdef.weight(); }
    void weight (unsigned w)		{ bdef.weight(w); }
    unsigned adjustedweight() const	{ return bdef.adjustedweight(); }

    unsigned connections() const 	{ return nconn; }
    unsigned connecterrors() const	{ return nconnerr; }
    
    double bytesserved() const		{ return bytes_served; }
    unsigned clientsserved() const	{ return totconn; }

    double loadavg() const		{ return loadaverage; }
    void loadavg(double l)		{ loadaverage = l; }

    void addbytes (unsigned n);
    void startconnection();
    void endconnection();    

    BackendDef const &backenddef() const {
	return bdef;
    }

    BackendCheck const &backendcheck() {
	return bdef.backendcheck();
    }
    void backendcheck(BackendCheck const &b) {
	bdef.backendcheck(b);
    }

    void balancerindex(int i)		{ index = i; }
    int balancerindex() const		{ return index; }
    

private:
    BackendDef bdef;
    bool islive;
    bool isup;
    int clsocket;
    unsigned nconn, totconn, nconnerr;
    double bytes_served;
    double loadaverage;
    DNSEntry dnsentry;
    int index;
};

#endif
