/**
 * @file TestSap.cpp
 * @date May 4, 2010
 * @author ron
 *
 * @brief
 */

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

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

	/**
	 * @struct SapFixture
	 * @brief Helper struct providing set-up/tear-down of Sap tests
	 *
	 * @copydetails EventFixture
	 */
	struct SapFixture
	{
		SuiteBase::SimulationTest sim;
		TestLogConsumer::Ptr log;
		data::TypeInfo bufHeadType;
		data::TypeInfo bufTailType;

		SapFixture()
		:	sim( "SapTestSim" )
		,	log( TestLogConsumer::create() )
		,	bufHeadType( typeid(odemx::synchronization::PortHeadT< PduPtr >) )
		,	bufTailType( typeid(odemx::synchronization::PortTailT< PduPtr >) )
		{
			sim.addConsumer( log );
		}
	};

	TEST_FIXTURE( SapFixture, Construction )
	{
		data::Label label = "SapTestConstruction";
		std::string name = "SAP";
		{
			Sap sap( sim, label, name );
			CHECK_EQUAL( name, sap.getName() );
			CHECK_EQUAL( label + " " + name + " buffer (head)", sap.getBuffer()->getLabel() );
			CHECK_EQUAL( odemx::synchronization::WAITING_MODE, sap.getBuffer()->getMode() );
			CHECK( log->getTraceRecord( "create", bufHeadType ) );
		}
		CHECK( log->getTraceRecord( "destroy", bufHeadType ) );
	}

	TEST_FIXTURE( SapFixture, Write )
	{
		Sap sap( sim, "SapTestWrite", "SAP" );
		PduPtr p( new PduTest );
		sap.write( p );
		CHECK( sap.getBuffer()->isAvailable() );
		CHECK_EQUAL( (std::size_t) 1, sap.getBuffer()->getBuffer().size() );
		CHECK_EQUAL( p, sap.getBuffer()->getBuffer().front() );
		CHECK( log->getTraceRecord( "put", bufTailType ) );
	}

	TEST_FIXTURE( SapFixture, Read )
	{
		Sap sap( sim, "SapTestRead", "SAP" );
		PduPtr p( new PduTest );
		sap.write( p );

		// can't call port in waiting mode, so change that first
		sap.getBuffer()->setMode( odemx::synchronization::ERROR_MODE );
		PduPtr pp = sap.read();
		CHECK_EQUAL( p, pp );
		CHECK( log->getTraceRecord( "get", bufHeadType ) );
		CHECK( ! sap.getBuffer()->isAvailable() );
	}
/// @cond DOXYGEN_SKIP
}
/// @endcond
