/**
 * @file TestSimRecordBuffer.cpp
 * @date May 3, 2010
 * @author ron
 *
 * @brief
 */


#include "../TestData.h"
#include "../../TestBase/TestBase.h"

/// @cond DOXYGEN_SKIP
SUITE( Data )
{
/// @endcond

	/**
	 * @struct SimRecordBufferFixture
	 * @brief Helper struct providing set-up/tear-down of SimRecordBuffer tests
	 *
	 * @copydetails EventFixture
	 */
	struct SimRecordBufferFixture
	{
		SuiteBase::SimulationTest sim;
		TestLogConsumer::Ptr log;
		ProducerTest producer;
		TypeInfo type;

		SimRecordBufferFixture()
		:	sim( "SimRecordBufferTestSim" )
		,	log( TestLogConsumer::create() )
		,	producer( sim, "SimRecordBufferTestFixtureProducer" )
		,	type( typeid(ProducerTest) )
		{
			sim.addConsumer( log );
		}
	};

	TEST_FIXTURE( SimRecordBufferFixture, Construction )
	{
		std::size_t limit = 100000;
		SimRecordBuffer buf( limit );
		CHECK_EQUAL( (std::size_t) 0, buf.getSize() );
		CHECK_EQUAL( limit, buf.getLimit() );
	}

	TEST_FIXTURE( SimRecordBufferFixture, Put )
	{
		SimRecordBuffer buf( 100000 );
		StringLiteral msg = "SimRecordBufferTestPut";
		std::string timeString( "2010-05-03 / 12:30:00" );
		SimRecord rec( sim, producer, msg );
		TableKey simId = 105;
		rec.detail( "SimRecordBufferTestPut", 234.6 ).scope( typeid(ProducerTest) );
		buf.put( channel_id::trace, rec, simId, timeString );

		CHECK( ! buf.isEmpty() );
		CHECK_EQUAL( (std::size_t) 1, buf.getSize() );
		CHECK_EQUAL( (std::size_t) 1, buf.getStorage().size() );

		const SimRecordBuffer::StoredRecord& bufRec = buf.getStorage().front();
		CHECK( bufRec.get< ChannelInfo >() );
		CHECK( bufRec.get< SenderLabelInfo >() );
		CHECK( bufRec.get< SenderTypeInfo >() );
		CHECK( bufRec.get< StringTimeInfo >() );
		CHECK( bufRec.get< SimIdInfo >() );
		CHECK( bufRec.get< ClassScopeInfo >() );
		CHECK( bufRec.hasDetails() );

		CHECK_EQUAL( msg, bufRec.getText() );
		CHECK_EQUAL( &rec.getDetails(), &bufRec.getDetails() );
		CHECK_EQUAL( channel_id::toString( channel_id::trace ), *bufRec.get< ChannelInfo >() );
		CHECK_EQUAL( producer.getLabel(), *bufRec.get< SenderLabelInfo >() );
		CHECK_EQUAL( producer.getType().toString(), *bufRec.get< SenderTypeInfo >() );
		CHECK_EQUAL( timeString, *bufRec.get< StringTimeInfo >() );
		CHECK_EQUAL( simId, *bufRec.get< SimIdInfo >() );
		CHECK_EQUAL( type.toString(), *bufRec.get< ClassScopeInfo >() );
	}

	TEST_FIXTURE( SimRecordBufferFixture, Clear )
	{
		SimRecordBuffer buf( 100000 );
		SimRecord rec( sim, producer, "SimRecordBufferTestClear" );
		buf.put( channel_id::debug, rec, 79, "2010-05-03 / 12:43:00" );

		buf.clear();
		CHECK( buf.isEmpty() );
		CHECK_EQUAL( (std::size_t) 0, buf.getSize() );
		CHECK_EQUAL( (std::size_t) 0, buf.getStorage().size() );
	}

	TEST_FIXTURE( SimRecordBufferFixture, IsFull )
	{
		SimRecordBuffer buf( 1 );
		SimRecord rec( sim, producer, "SimRecordBufferTestIsFull" );

		buf.put( channel_id::debug, rec, 20, "2010-05-03 / 12:46:00" );
		CHECK( buf.isFull() );
	}
/// @cond DOXYGEN_SKIP
}
/// @endcond
