//
// Copyright (c) 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 TestChannel.cpp
 * @author Ronald Kluth
 * @date created at 2009/05/16
 * @brief Unit tests for class template Channel
 * @since 0.1
 */

#include "global.h"
#include <string>

SUITE( CppLogUnitTest )
{
	template< typename RecordT >
	struct DummyConsumer: public Log::Consumer< RecordT >
	{
		virtual void consume( const Log::ChannelId channelId, const RecordT& record )
		{
			lastChannelId = channelId;
			lastRecord = record;
		}
		Log::ChannelId lastChannelId;
		RecordT lastRecord;
	};

	struct TestChannelFixture
	{
		typedef Log::Channel< std::string > Channel;
		typedef std::tr1::shared_ptr< Channel > ChannelPtr;
		typedef Log::Filter< std::string > Filter;
		typedef std::tr1::shared_ptr< Filter > FilterPtr;
		typedef DummyConsumer< std::string > Consumer;
		typedef std::tr1::shared_ptr< Consumer > ConsumerPtr;

		TestChannelFixture()
		:	channelId( 99 )
		,	channel( channelId )
		{}

		Log::ChannelId channelId;
		Channel channel;
	};

	TEST_FIXTURE( TestChannelFixture, Id )
	{
		CHECK_EQUAL( channel.getId(), channelId );
	}

	TEST_FIXTURE( TestChannelFixture, Filter )
	{
		FilterPtr filter( new Filter() );
		channel.setFilter( filter );
		CHECK( channel.hasFilter() );
		CHECK_EQUAL( filter, channel.getFilter() );

		channel.resetFilter();
		CHECK( ! channel.hasFilter() );
	}

	TEST_FIXTURE( TestChannelFixture, Consumers )
	{
		ConsumerPtr con1( new Consumer() );
		ConsumerPtr con2( new Consumer() );
		ConsumerPtr con3( new Consumer() );
		channel.addConsumer( con1 );
		channel.addConsumer( con2 );
		channel.addConsumer( con3 );

		const Channel::ConsumerSet& cons = channel.getConsumers();
		CHECK( cons.find( con1 ) != cons.end() );
		CHECK( cons.find( con2 ) != cons.end() );
		CHECK( cons.find( con3 ) != cons.end() );

		channel.removeConsumer( con2 );
		CHECK( cons.find( con1 ) != cons.end() );
		CHECK( cons.find( con2 ) == cons.end() );
		CHECK( cons.find( con3 ) != cons.end() );

		channel.removeConsumers();
		CHECK( cons.empty() );
	}

	TEST_FIXTURE( TestChannelFixture, Inserters )
	{
		ConsumerPtr con( new Consumer() );
		channel.addConsumer( con );
		std::string record( "Channel Object Inserter Test" );
		channel << record;
		CHECK_EQUAL( record, con->lastRecord );
		CHECK_EQUAL( channel.getId(), con->lastChannelId );

		ChannelPtr p_channel( new Channel( channelId + 1 ) );
		p_channel->addConsumer( con );
		record = "Channel Pointer Inserter Test";
		p_channel << record;
		CHECK_EQUAL( record, con->lastRecord );
		CHECK_EQUAL( p_channel->getId(), con->lastChannelId );

		p_channel.reset();
		record.clear();
		p_channel << record;
		CHECK( ! con->lastRecord.empty() );
	}
}
