/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    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 DDWEBSERVER_H
#define DDWEBSERVER_H

#include <ddbaseobject.h>
#include <ddconfig.h>
#include <ddusermanager.h>
#include <ddmimemap.h>
#include <ddiobuffer.h>
#include <dditemset.h>
#include <ddthreadmutex.h>

#include <ddstringset.h>
#include <ddwebconnection.h>
#include <ddwebrequest.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <ddthreadrunnable.h>
#include <ddthreadmutex.h>
#include <netinet/in.h>

using namespace std;

/// ddwebsocket
/**
	The main server socket.
*/

class ddwebserver;
class ddconfigsection;

class ddwebsocket : public ddbaseobject
{
		
public:

	ddwebsocket()
	: _fd( -1 )
	{
	}
	
	void listen( int port, int backlog=DDIOBACKLOG );	
	void close();	
	
	/**
  	Returns the filedescriptor. Can be -1.
  */

	inline int get_fd()
  {
  	return _fd;
  }	
		
protected:
	
	int         _fd;
	sockaddr_in _sa_local;
	
};


/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    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.

***************************************************************************/


class ddwebpage;
class ddwebsite;

typedef ddmapptr<ddwebsite> ddwebsitemap;
typedef vector<ddwebconnection*> ddconnvec;
typedef void (*ddfncall)(int);

class ddwebconfig : public ddconfigoptions
{

public:
	
		ddwebconfig();
		
};


/// ddwebserver: der supportware web application server in seiner ganzen Pracht.
/**
	Der Webserver ist die eigentliche Application, er ist ein connectionpool, der
	ddwebsites enthält, an die die user requests weitergeleitet werden. 
	@see ddwebsite
*/


class ddwebserver : public ddbaseobject
{

public:
  
  ddwebserver();
	virtual ~ddwebserver();
	
	
	/**
  	Gibt eine Referenz auf die Liste von gesperrten IPs
  	zurück.  
  */
  
  inline ddstringrowset& get_blocked_ips()
  {
  	return _blockedips;
  }
	
	
	/**
  	Gibt eine Referenz auf die Liste von gesperrten eMails
  	zurück.  
  */
  
  inline ddstringset& get_blocked_mails()
  {
  	return _blockedmails;
  }
	
	
	/**
  	Gibt eine Referenz auf die config	zurück.  
  */
  
  inline const ddconfig& get_config() const
  {
  	return _config;
  }
	
	// connectionpool aspekt
	
	/**
		Gibt die Anzahl gerade aktiver Connections zurück.
	*/
	
	inline size_t	num_active_connections()
	{
		return _activeconnections;
	}
	
	/**
		Gibt die aktuelle Anzahl an Connections zurück.
	*/
	
	inline size_t	num_connections()
	{
		return _allconnections.size();
	}

	
	/**
		Gibt den (für alle Sites) zentralen
		Usermanager zurück
		@see ddusermanager
	*/
	
	inline ddusermanager& get_user_manager()
  {
  	return _usermanager;
  }
	
	
	/**
		@return Die Startzeit
	*/
	
	inline const ddstring& get_start_time()
  {
  	return _starttime;
  }
  
  
  /**
		@return den mimetype für eine dateiendung.
	*/

	inline const ddstring& get_mime_type( const ddstring& filetype )
	{
		return _mimemap.get_entry( filetype );
	}
	
	// server aspekt
	void        			add_site( const ddstring& key, ddwebsite* site, const ddstring& title );
	void        			run( int argc, char** argv, const ddstring& configfile="" );
  void        			halt();
	int			  				webserver_handle_request( ddwebconnection& connection );
  
  static int  			sig_init( int sig, ddfncall function );
  static void 			sig_handler(int sig);

protected:

  void							init_connection_pool( ddconfigsection& config );
	void    					process_connections();
	void	  					prepare_connections();
	void    					poll_connections();
 	ddwebconnection*	find_connection();
 
 	void      				change_user_root( const ddstring& user, const ddstring& newroot );
  void      				change_daemon();
	void      				rotate_log_streams( time_t lasttime );

	//-- connectionpool aspekt
	
	int   						_maxconnections;
	int   						_activeconnections;
	size_t						_timeout;
	struct pollfd*  	_pollfds;	
	bool							_halted;

	int 							_fdno;
	int								_fifo;
	ddwebconnection*	_cfree;
	ddwebsocket 			_socket;	
	// speichert die connections dauerhaft
	ddconnvec 				_allconnections;
	// speichert die connections temporär als 'watchset'
	ddconnvec					_tmpconnections;
	char              _dummybuf[100];
	ddstringrowset		_blockedips;	
	ddstringset				_blockedmails;
	
	//-- application server aspekt
	
	ddwebsitemap			_sites;
	ddmimemap					_mimemap;
	ddconfig	        _config;
  ddwebconfig			  _configoptions;
  ddthreadmutex     _errorpagemutex;
 	
 	ddstring				  _starttime;
	ddusermanager     _usermanager;

private:

	ddwebserver( const ddwebserver& src );
	ddwebserver& operator=( const ddwebserver& src );

};




#endif
