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

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

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

	/**
	 * @struct XmlWriterFixture
	 * @brief Helper struct providing set-up/tear-down of XmlWriter tests
	 *
	 * @copydetails EventFixture
	 */
	struct XmlWriterFixture
	{
		SuiteBase::SimulationTest sim;
		std::string fileNameBase;
		ProducerTest producer;
		TypeInfo type;

		XmlWriterFixture()
		:	sim( "XmlWriterTestSim" )
		,	fileNameBase( "XmlWriterTest" )
		,	producer( sim, "XmlWriterTestProducer" )
		,	type( typeid(ProducerTest) )
		{}
	};

	TEST_FIXTURE( XmlWriterFixture, Construction )
	{
		{
			XmlWriterPtr xmlWriter = XmlWriter::create( fileNameBase, 10 );
		}
		CHECK( Poco::File( fileNameBase + ".html" ).exists() );
		CHECK( Poco::File( fileNameBase + "_0.xml" ).exists() );
		CHECK( Poco::File( fileNameBase + "_file_info.xml" ).exists() );
	}

	TEST_FIXTURE( XmlWriterFixture, Consume )
	{
		StringLiteral msg = "XmlWriterTestConsume";
		StringLiteral detName = "DetailConsume";
		int detVal = 9631.45;
		{
			XmlWriterPtr xmlWriter = XmlWriter::create( fileNameBase );
			sim.addConsumer( channel_id::info, xmlWriter );
			producer.info << producer.log( msg ).detail( detName, detVal ).scope( type );
			sim.removeConsumer( channel_id::info, xmlWriter );
		}

		std::ifstream is( ( fileNameBase + "_0.xml" ).c_str(), std::ifstream::in );
		std::ostringstream stream;
		while( is.good() )
		{
			stream.put( is.get() );
		}

		CHECK( stream.str().find( "<odemxlog>" ) != std::string::npos );
		CHECK( stream.str().find( "<record>" ) != std::string::npos );
		CHECK( stream.str().find( "<time>" ) != std::string::npos );
		CHECK( stream.str().find( "</time>" ) != std::string::npos );
		CHECK( stream.str().find( "<channel>" ) != std::string::npos );
		CHECK( stream.str().find( channel_id::toString( channel_id::info ) ) != std::string::npos );
		CHECK( stream.str().find( "</channel>" ) != std::string::npos );
		CHECK( stream.str().find( "<text>" ) != std::string::npos );
		CHECK( stream.str().find( msg.c_str() ) != std::string::npos );
		CHECK( stream.str().find( "</text>" ) != std::string::npos );
		CHECK( stream.str().find( "<senderlabel>" ) != std::string::npos );
		CHECK( stream.str().find( producer.getLabel() ) != std::string::npos );
		CHECK( stream.str().find( "</senderlabel>" ) != std::string::npos );
		CHECK( stream.str().find( "<sendertype>" ) != std::string::npos );
		CHECK( stream.str().find( producer.getType().toString() ) != std::string::npos );
		CHECK( stream.str().find( "</sendertype>" ) != std::string::npos );
		CHECK( stream.str().find( "<detail>" ) != std::string::npos );
		CHECK( stream.str().find( "<name>" ) != std::string::npos );
		CHECK( stream.str().find( detName.c_str() ) != std::string::npos );
		CHECK( stream.str().find( "</name>" ) != std::string::npos );
		CHECK( stream.str().find( "<value>" ) != std::string::npos );
		CHECK( stream.str().find( toString( detVal ) ) != std::string::npos );
		CHECK( stream.str().find( "</value>" ) != std::string::npos );
		CHECK( stream.str().find( "</detail>" ) != std::string::npos );
		CHECK( stream.str().find( "</record>" ) != std::string::npos );
		CHECK( stream.str().find( "</odemxlog>" ) != std::string::npos );

	}

	TEST_FIXTURE( XmlWriterFixture, SetTimeFormat )
	{
		Iso8601Time format( TimeBase( 2010, 5, 3, 21*60+44, TimeUnit::minutes ) );
		base::SimTime time = 480;
		sim.setCurrentTime( time );
		StringLiteral msg = "XmlWriterTestSetTimeFormat";
		{
			XmlWriterPtr xmlWriter = XmlWriter::create( fileNameBase );
			xmlWriter->setTimeFormat( new Iso8601Time( format ) );
			sim.addConsumer( channel_id::info, xmlWriter );
			producer.info << producer.log( msg );
			sim.removeConsumer( channel_id::info, xmlWriter );
		}
		std::ifstream is( ( fileNameBase + "_0.xml" ).c_str(), std::ifstream::in );
		std::ostringstream stream;
		while( is.good() )
		{
			stream.put( is.get() );
		}

		CHECK( stream.str().find( format.timeToString( time ) ) != std::string::npos );
	}

	TEST_FIXTURE( XmlWriterFixture, StartNewFile )
	{
		XmlWriterPtr xmlWriter = XmlWriter::create(	fileNameBase, 3 );
		sim.addConsumer( channel_id::info, xmlWriter );

		int i = 4;
		while( i-- )
		{
			sim.setCurrentTime( sim.getTime() + 1 );
			producer.info << producer.log( "XmlWriterTestStartNewFile" );
		}
		sim.removeConsumer( channel_id::info, xmlWriter );
		xmlWriter.reset(); // should destroy the writer and close the file

		Poco::File file( fileNameBase + "_1.xml" );
		CHECK( file.exists() );

		std::ifstream is( ( fileNameBase + "_file_info.xml" ).c_str(), std::ifstream::in );
		std::ostringstream stream;
		while( is.good() )
		{
			stream.put( is.get() );
		}

		CHECK( stream.str().find( fileNameBase + "_0.xml" ) != std::string::npos );
		CHECK( stream.str().find( fileNameBase + "_1.xml" ) != std::string::npos );
	}

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