//////////////////////////////////////////////////////////////////////////////
//
// Asura_UnitTest_MSStreamLoader.cpp
//
// Copyright (c) 2008 Rebellion. All rights reserved.
//
// Description:
//
//     tests for multithreaded streaming music code
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

#if defined(ASURA_SUPPORT_UNITTEST)

#include "Core/Threads/Asura_ProducerConsumerQueue.h"
#include "Sound/Asura_Sound.h"
#include "Sound/Asura_PS3_Sound_System.h"
//#include "Sound/Asura_PS3_MultiStream_Streaming.h"  //included by, and depends on, Asura_PS3_Sound_System.h... what a rat's nest
#include "Debugging/Asura_Logfile.h"
#include "UnitTest/Asura_UnitTest.h"


static Asura_PS3_MSStreamingSound g_xTestSound; //allocs some stuff in it's constructor, which we then access from our asynchronous loaders, so can't give it local scope.


#define RunTests( g_xTestSound, bPlaying, bDead ) \
	{																																\
		/*call a bunch of Asura_PS3_MSStreamingSound functions*/																	\
		/*but NOT Play() since that does some of our loading*/																		\
		ASURA_UNITTEST_CHECK( g_xTestSound.IsFinished() != bPlaying );																		\
																																	\
		ASURA_UNITTEST_CHECK( g_xTestSound.IsValid() != bDead );																			\
																																	\
		/*UNITTEST_MSSTREAMLOADER_OUTPUT(("length is: %fs\n", g_xTestSound.GetLength()));*/													\
		/*UNITTEST_MSSTREAMLOADER_OUTPUT(("position is: %fs\n", g_xTestSound.GetPosition()));*/												\
																																	\
		/* now call a bunch of funcs to try and break them */																		\
		g_xTestSound.Pause();																												\
		g_xTestSound.Resume();																												\
		g_xTestSound.SetVolume( 0.5f );																										\
		g_xTestSound.UpdateVolume();																										\
	}

#if (0)
	#define UNITTEST_MSSTREAMLOADER
	#define UNITTEST_MSSTREAMLOADER_OUTPUT(p) Asura_OutputToDebugger(p)
#else
	#define UNITTEST_MSSTREAMLOADER_OUTPUT(p)
#endif

void EmptyFunc( void *pNull, u_int uZero )
{
	return;
}


ASURA_UNITTEST(AsyncLoader, PS3_MultiStream)
{
	bool bRet;

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\n"));
	
	Asura_OutputToDebugger(("Running MSStreamingSound unit test\n")); //the streaming sound module chucks out a load of text to tty, so it's worth giving it a header

	//simulated bad cases
	//the loading & deiniting is queued on a seperate thread, so happens at an indeterministic place in this.
	//BW would be better to test by forcing it to run things when I tell it. I did test it like this prior to using Asura_ProducerConsumerQueue.
	
	//for starters, check that length == 0.0f after Asura_PS3_MSStreamingSound::Create before Asura_PS3_MSStreamLoader::Load
	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nTest 1.1: create\n"));
	bRet = g_xTestSound.Create( "SOUNDS/STREAMS/ENGLISH/CUTSCENE/cs_m10_casper.mp3", Asura_Sound_System::SoundGroup_Music );
	ASURA_UNITTEST_CHECK(bRet);
	RunTests(g_xTestSound,true,false);
	
	UNITTEST_MSSTREAMLOADER_OUTPUT(("\nTest 1.2: play\n"));
	g_xTestSound.Play(false,false);
	RunTests(g_xTestSound,true,false);

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\nTest 1.3: update (do nothing)\n"));
	g_xTestSound.Update();
	RunTests(g_xTestSound,true,false);

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nTest 2: stop\n"));
	g_xTestSound.Stop();
	RunTests(g_xTestSound,false,false);

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nTest 3: destroy\n"));
	g_xTestSound.Destroy();
	RunTests(g_xTestSound,false,true);
	
#ifdef UNITTEST_MSSTREAMLOADER
	//this one should fail and fling an assert
	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nTest 4.1: overload queue & loaders\n"));
	Asura_PS3_MSStreamingSound aTest[5];
	for ( int i=0; i < 5; i++ )
	{
		bRet = aTest[i].Create( "SOUNDS/STREAMS/ENGLISH/CUTSCENE/m10_griffin.mp3", Asura_Sound_System::SoundGroup_Music );
		ASURA_UNITTEST_CHECK(bRet);
	}

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nTest 4.2: destroy them\n"));
	for ( int i=0; i < 5; i++ )
	{
		aTest[i].Destroy();
	}
#endif

	UNITTEST_MSSTREAMLOADER_OUTPUT(("\n\nDone!\n\n"));

#ifdef UNITTEST_MSSTREAMLOADER
	ASURA_PS3_DEBUGBREAK();
#endif

	//BW Note: the async loading could still be running. Ideally this unit test should be in charge of that stuff but at present that would mean changing the code being tested.
}

#endif // ASURA_SUPPORT_UNITTEST
