/*
 * The UDS Collection
 * Copyright (C) 2000, 2001  Julian v. Bock
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *	(See file COPYING for more information)
 */

#ifndef _uds_syslog_hh
#define _uds_syslog_hh


// includes

#include <fstream>
#include <string>
#include <syslog.h>

using namespace std;


namespace uds
{

/** manages a log file. Log messages can appended to a log file and / or
	passed to the syslog daemon.
	\author Julian v. Bock */
class Logger
{
public:
	/** type for log levels. valid values range from 0 to 8, where 8 means
		that everything is logged, and 0 that everything is ignored. */
	typedef unsigned char loglev_t;
	
	/** flag type */
	typedef unsigned char flag_t;
	
	/** flag values */
	enum
	{
		use_ident	= 0x1,	///< use ident string in log file
		log_pid		= 0x2,	///< log pid in log file
		no_newlines	= 0x4,	///< replace newlines with spaces
		add_tabs	= 0x8,	///< add tabs after newlines
		print_pri	= 0x10,	///< print priority
		print_time	= 0x20	///< print the time with each message
	};
	
	/**	\param s log level for syslog daemon
		\param p log level for private logfile */
	Logger( loglev_t s = 0, loglev_t p = 0 );
	
	/** destructor */
	~Logger();
	
	/** returns the log level for the private log file
		\return log level */
	loglev_t
	PLogLevel() const { return ll_priv; }
	
	/** sets the log level for the private log file
		\param l new log level
		\return old log level */
	loglev_t
	PLogLevel( loglev_t l ) { loglev_t o = ll_priv; ll_priv = l; return o; }
	
	/** returns the log level for the syslog daemon
		\return log level */
	loglev_t
	SLogLevel() const { return ll_sys; }
	
	/** sets the log level for the syslog daemon
		\param l new log level
		\return old log level */
	loglev_t
	SLogLevel( loglev_t l ) { loglev_t o = ll_sys; ll_sys = l; return o; }
	
	/** opens a new log file.
		\param id ident string
		\param file log file name
		\param flags flags */
	void
	OpenLog( const string& id, const char* file, flag_t f );
	
	/** opens a connection to the system logger.
		see man 3 syslog for the meaning of the opt and fac arguments.
		\param id ident string
		\param opt syslog option
		\param fac syslog facility
		\param f flags */
	void
	OpenLog( const string& id, int opt, int fac );
	
	/** opens a connection to the system logger and / or opens a new log file.
		see man 3 syslog for the meaning of the opt and fac arguments.
		\param id ident string
		\param file log file name
		\param opt syslog option
		\param fac syslog facility
		\param f flags */
	void
	OpenLog( const string& id, const char* file, int opt, int fac, flag_t f );
	
	/** closes log files / syslog connection */
	void
	CloseLog();
	
	/** logs a message. the message is printed if priority < log level.
		\param p priority
		\param m message */
	void
	operator () ( loglev_t p, const string& m ) const;
	
	/** checks whether a message with a given priority would be logged
		\param p priority */
	bool
	operator () ( loglev_t p ) const { return p < ( ll_sys >? ll_priv ); }
	
private:
	/// log file name
	string			logfile;
	/// file stream used for logging
	mutable fstream	log;
	/// ident string
	string			ident;
	/// log level (syslog daemon)
	loglev_t		ll_sys;
	/// log level (private logfile)
	loglev_t		ll_priv;
	/// flags
	flag_t			flags;
};

}

#define _uds_Log( logger, lev, msg )                                         \
	if ( logger( lev ) )                                                     \
		logger( lev, msg )

#endif // _uds_syslog_hh
