//------------------------------------------------------------------------------
//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library 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
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/**
 * @file LoggingManager.h
 * @author Ronald Kluth
 * @date created at 2009/03/18
 * @brief Declaration of odemx::data::LoggingManager
 * @sa LoggingManager.cpp
 * @since 3.0
 */

#ifndef ODEMX_DATA_LOGGINGMANAGER_INCLUDED
#define ODEMX_DATA_LOGGINGMANAGER_INCLUDED

#include <odemx/setup.h>
#include <odemx/base/SimTime.h>
#include <odemx/data/ManagedChannels.h>
#include <odemx/data/SimRecord.h>
#include <odemx/data/output/DefaultLoggingType.h>
#include <CppLog/ChannelManager.h>

#include <string>

namespace odemx {
namespace data {

//----------------------------------------------------------forward declarations

class StatisticsReport;
struct DefaultLogConfig;

//-----------------------------------------------------------header declarations

/**
 * @brief Facilitates log channel management, error logging, and default logging
 * @ingroup data
 * @author Ronald Kluth
 * @since 3.0
 * @see odemx::data::Producer, ODEMX_DECLARE_DATA_CHANNEL
 *
 * The logging manager is a base class for the simulation context. It is
 * primarily responsible for creating and providing access to the log
 * channels that ODEMx provides by default:
 * @li trace
 * @li debug
 * @li info
 * @li warning
 * @li error
 * @li fatal
 * @li statistics
 *
 * All of those channels use the record type @c odemx::data::SimRecord.
 * Access to the channels is automatically provided within subclasses of
 * @c odemx::data::Producer.
 *
 * Another function of this class is the provision of a name scope for
 * uniquely labeled objects within one simulation context. All data producers
 * must request a label from the logging manager, which will ensure its
 * uniqueness by appending numbers if a particular label already exists.
 *
 * Finally, the class handles the initialization of error logging components.
 * The channels warning, error and fatal can be used by data producers to
 * notify the user of possible problems. Upon initialization of the manager,
 * it creates an instance of odemx::data::output::ErrorWriter and   registers
 * it with these channels.
 *
 * @note Care must be taken if all consumers are removed from a log channel,
 * as this will include the error writer as well.
 */
class LoggingManager
:	public Log::ChannelManager< SimRecord >
{
public:
	/// Construction
	LoggingManager();
	/// Construction with different default label and spacer for named elements
	LoggingManager( const std::string& defLabel, const char defSpace );
	/// Destruction
	virtual ~LoggingManager();

	/**
	 * @brief Activates the default logging functionality
	 * @param type Determines the type of logging consumer used
	 * @param location Determines the location for XML and database output
	 * @retval @c true if the activation was successful
	 * @retval @c false if the the default logging was already enabled
	 *
	 * Default logging simply means initializing one log consumer and
	 * registering that with all provided channels. The type of the log
	 * consumer can be determined by the first parameter:
	 * @li STDOUT creates an odemx::data::output::OStreamWriter for the console
	 * @li XML creates an odemx::data::output::XmlWriter for XML file output.
	 * This requires the provision of a base name for the files as second argument.
	 * @li DATABASE creates an odemx::data::output::DatabaseWriter. This also
	 * requires a second argument, which must be a connection string for the
	 * target database. In the case of SQLite, this will be a file name.
	 * When using ODBC, it must specify driver and user settings.
	 *
	 * Additionally, an odemx::data::buffer::StatisticsBuffer object is
	 * registered with the statistics channel in order to automatically
	 * collect statistical data.
	 */
	bool enableDefaultLogging( output::Type type, const std::string& location = "" );

	/**
	 * @brief Deactivates the default logging functionality
	 * @retval @c true if the deactivation was successful
	 * @retval @c false if the the default logging was not enabled
	 *
	 * Both, the default writer, and the statistics buffer objects will be
	 * removed from the channels and thereby be destroyed.
	 */
	bool disableDefaultLogging();

	/**
	 * @brief Reset the data stored in the statistics buffer
	 * @param currentTime The current simulation time passed to the statistics buffer.
	 * @retval @c true if the reset was successful
	 * @retval @c false if the the default logging was disabled
	 * @note This requires the default logging to be active
	 */
	bool resetDefaultStatistics( base::SimTime currentTime );

	/**
	 * @brief Create a report from the collected statistical data
	 * @param type SDTOUT or XML to choose where to create the report
	 * @param location Required when using XML, this will be used as file name.
	 * @retval @c true if the reset was successful
	 * @retval @c false if the the default logging was disabled
	 * @note This requires the default logging to be active
	 */
	bool reportDefaultStatistics( output::Type type, const std::string& location = "" );

private:
	/// Manages the default logging configuration, if one is set
	std::auto_ptr< DefaultLogConfig > defaultLogConfig_;

private:
	/**
	 * @brief Registers an ErrorWriter with channels warning, error and fatal.
	 *
	 * This helper method is called automatically during construction.
	 */
	void initErrorLogging();
};

} } // namespace odemx::data

#endif /* ODEMX_DATA_LOGGINGMANAGER_INCLUDED */
