//
// Copyright (c) 2009-2010 Ronald Kluth
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

/**
 * @file Example_Producer_ChannelManager.cpp
 * @author Ronald Kluth
 * @date 2009/11/22
 * @brief Example introducing basic producer and channel manager usage
 * @since 0.1
 */

/**
 * @example Example_Producer_ChannelManager.cpp
 *
 * This example illustrates the basic usage of the class templates @c Producer
 * and @c ChannelManager. First, the record type is defined as a pair of two
 * strings, followed by the declaration of two channels: @c info and @c debug.
 * The IDs of the channels are used to enable channel members within the
 * @c Producer template by providing an instance of @c Enable as template
 * parameter. By deriving from the resulting type, class @c ExampleProducer
 * can access the two channel members @c info and @c debug directly.
 *
 * Since a user-defined record type is employed, we must provide a suitable 
 * consumer type: the class @c ConsoleWriter. It uses the channel IDs to
 * print information about the forwarding channel.
 *
 * In the main function, a @c ChannelManager is created, which is used in the
 * initialization of two producer objects. By adding a consumer to the manager,
 * it is automatically registered with all currently managed channels, and
 * the records sent by both producers are printed on the console.
 */

#include <CppLog.h>
#include <iostream>

typedef std::pair< std::string, std::string > Rec;

CPPLOG_DECLARE_CHANNEL_WITH_ID( channel, info, Rec, 1 );
CPPLOG_DECLARE_CHANNEL_WITH_ID( channel, debug, Rec, 2 );

typedef Log::Producer< Log::Enable< channel::info, channel::debug > > ProducerType;

class DataProducer: public ProducerType {
public:
	DataProducer( Log::ChannelManager< Rec >& mgr, const std::string& name )
	:	ProducerType( mgr , name ) {}
	void useInfo() {
		info << log( "Info logging with Producer and ChannelManager" );
	}
	void useDebug() {
		debug << log( "Debug logging with Producer and ChannelManager" );
	}
private:
	Rec log( const std::string& text ) const { return Rec( getName(), text ); }
};

class ConsoleWriter: public Log::Consumer< Rec > {
public:
	virtual void consume( const Log::ChannelId channelId, const Rec& record ) {
		switch( channelId ) {
			case channel::info: std::cout << "INFO "; break;
			case channel::debug: std::cout << "DEBUG "; break;
			default: break;
		}
		std::cout << "(" << record.first << ") " << record.second << std::endl;
	}
};

int main() {
	typedef std::tr1::shared_ptr< Log::Consumer< Rec > > ConsumerPtr;
	Log::ChannelManager< Rec > manager;
	DataProducer p1( manager, "P1" ), p2( manager, "P2" );
	manager.addConsumer( ConsumerPtr( new ConsoleWriter() ) );
	p1.useInfo();
	p2.useDebug();
}
