/**
 * @file TestEntity.cpp
 * @date May 5, 2010
 * @author ron
 *
 * @brief
 */

#include "TestProtocol.h"
#include "../TestBase/TestBase.h"

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

	/**
	 * @struct EntityFixture
	 * @brief Helper struct providing set-up/tear-down of Entity tests
	 *
	 * @copydetails EventFixture
	 */
	struct EntityFixture
	{
		SuiteBase::SimulationTest sim;
		TestLogConsumer::Ptr log;
		EntityTest ent;
		data::TypeInfo type;

		EntityFixture()
		:	sim( "EntityTestSim" )
		,	log( TestLogConsumer::create() )
		,	ent( sim, "EntityTest" )
		,	type( typeid(Entity) )
		{
			sim.addConsumer( log );
		}
	};

	TEST_FIXTURE( EntityFixture, Construction )
	{
		data::Label label = "EntityTestConstruction";
		EntityTest ent( sim, label );
		CHECK_EQUAL( label, ent.getLabel() );
	}

	TEST_FIXTURE( EntityFixture, Send )
	{
		Layer layer( sim, "EntityTestSendLayer" );
		Layer layer2( sim, "EntityTestSendLayer" );

		layer.setLowerLayer( &layer2 );
		ent.setLayer( &layer );

		ent.send( "SAP", PduPtr( new PduTest() ) );
		CHECK( log->getWarningRecord( "Entity::send(): "
				"lower layer does not offer SAP", type ) );

		std::auto_ptr< Sap > sap( new Sap( sim, "EntityTestSendSap", "SAP" ) );
		layer2.addSap( sap.get() );
		ent.send( "SAP", PduPtr( new PduTest() ) );
		CHECK( log->getTraceRecord( "send", type ) );
		CHECK_EQUAL( (std::size_t) 1, sap->getBuffer()->count() );
	}

	TEST_FIXTURE( EntityFixture, Pass )
	{
		Layer layer( sim, "EntityTestPassLayer" );
		Layer layer2( sim, "EntityTestPassLayer" );

		layer.setUpperLayer( &layer2 );
		ent.setLayer( &layer );
		ent.pass( "SAP", PduPtr( new PduTest() ) );
		CHECK( log->getWarningRecord( "Entity::pass(): "
				"upper layer does not offer SAP", type ) );

		std::auto_ptr< Sap > sap( new Sap( sim, "EntityTestPassSap", "SAP" ) );
		layer2.addSap( sap.get() );
		ent.pass( "SAP", PduPtr( new PduTest() ) );
		CHECK( log->getTraceRecord( "pass", type ) );
		CHECK_EQUAL( (std::size_t) 1, sap->getBuffer()->count() );
	}

/// @cond DOXYGEN_SKIP
}
/// @endcond
