//===========================================================================//
// File:        RESOURCE_test.CPP														  //
// Project: MUNGA           Brick: Resource Manager                          //
// Contents: Implementation Details of resource managment                    //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 01/20/95  GSY  Initial coding.                                            //
// 01/20/95  GAH  Added MUNGA style comments and assertions.                 //
// 06/14/96  GAH  Added preload, referential resource type, the ability to   //
//                load resources from separate resource files.               //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide.                                            //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL.              //
//===========================================================================//

#include "AdeptHeaders.hpp"

//
//#############################################################################
//#############################################################################
//
#if 0
static int
	ResourceManager_RandInt(int x)
{
	return Random::GetLessThan(x);
}

static MString
	ResourceManager_GenerateName(int count)
{
	char buffer[256];
	return "resource" + MString(_itoa(count, buffer, 10));
}

static void
	ResourceManager_GenerateStream(DynamicMemoryStream *stream, int count)
{
	size_t resource_len = (count % (1024*1024/4)) + 1;

	Check_Object(stream);
	for (int i = 0; i < resource_len; i++)
	{
		stream->WriteBytes(&i, sizeof(i));
	}
}

static void
	ResourceManager_CompareStream(
		DynamicMemoryStream *stream1,
		DynamicMemoryStream *stream2
	)
{
	Check_Object(stream1);
	Check_Object(stream2);

	stream1->Rewind();
	stream2->Rewind();
	
	Verify(
		stream1->GetStreamLength() == 
		stream2->GetStreamLength()
	);

	Verify(
		memcmp(
			stream1->GetPointer(),
			stream2->GetPointer(),
			stream1->GetStreamLength()
		) == 0
	);
}
#endif

//
//#############################################################################
//#############################################################################
//
void
	ResourceManager::TestClass()
{
	Check_Object(ResourceManager::Instance);
	STOP(("Not implemented"));
#if 0

	//
	// Open a 2 test files
	//
	ResourceManager::Instance->OpenResourceFile(
		"Content\\TestResources1",
		0,
		false,
		true
	);
	
	//
	// Generate test resources
	//
	int i, number_of_resources = 1000;

	for (i = 0; i < number_of_resources; i++)
	{
		DynamicMemoryStream resource_stream;		
		ResourceManager_GenerateStream(&resource_stream, i);

		ResourceDescription *resource_description;

		resource_description = ResourceManager::Instance->AddResource(
			ResourceManager_GenerateName(i),
			i % 10,
			&resource_stream,
			(i % 5 == 0) ? 
				ResourceDescription::Preload : 
				ResourceDescription::NoAttributes
		);
		Check_Object(resource_description);
	}
	Verify(ResourceManager::Instance->GetResourceCount() == number_of_resources);

	//
	// Verify that the resources can be retrieved correctly, and match
	// the ones generated
	//
	for (i = 0; i < number_of_resources; i++)
	{
		ResourceDescription *resource_description;

		int j = ResourceManager_RandInt(number_of_resources);
		MString resource_name = ResourceManager_GenerateName(j);
		ResourceType type = j % 10;
		
		DynamicMemoryStream resource_stream;
		ResourceManager_GenerateStream(&resource_stream, j);

		resource_description = ResourceManager::Instance->GetResource(
			resource_name,
			type
		);
		Check_Object(resource_description);		
		resource_description->Lock();
		Verify(resource_description->recordName == resource_name);
		Verify(resource_description->recordType == type);		
		ResourceManager_CompareStream(
			&resource_stream, 
			resource_description->recordData
		);
		resource_description->Unlock();

		resource_description = ResourceManager::Instance->GetResource(
			resource_description->resourceID
		);
		Check_Object(resource_description);
		resource_description->Lock();
		Verify(resource_description->recordName == resource_name);
		Verify(resource_description->recordType == type);		
		ResourceManager_CompareStream(
			&resource_stream, 
			resource_description->recordData
		);
		resource_description->Unlock();
	}

	//
	// Sequence through all records
	//
	ResourceManager::Instance->First();
	for (i = 0; i < number_of_resources; i++)
	{
		ResourceDescription *resource_description;

		resource_description = ResourceManager::Instance->ReadAndNext();
		Check_Object(resource_description);
	}

	//
	// Delete a set of records that fit a specific distribution
	//
	for (i = 0; i < number_of_resources; i++)
	{
		if (i % 10 == 0)
		{
			ResourceDescription *resource_description;

			MString resource_name = ResourceManager_GenerateName(i);
			ResourceType type = i % 10;
			
			resource_description = ResourceManager::Instance->GetResource(
				resource_name,
				type
			);
			Check_Object(resource_description);
			ResourceManager::Instance->DeleteResource(resource_description);
		}
	}

	//
	// Verify that those records do not show up 
	//
	for (i = 0; i < number_of_resources; i++)
	{
		if (i % 10 == 0)
		{
			ResourceDescription *resource_description;

			MString resource_name = ResourceManager_GenerateName(i);
			ResourceType type = i % 10;
			
			resource_description = ResourceManager::Instance->GetResource(
				resource_name,
				type
			);
			Verify(resource_description == NULL);
		}
	}

	//
	// Run stress test
	//
	const int iterations = 1000;	
	
	for (i = number_of_resources; i < number_of_resources+iterations; i++)
	{
		switch (ResourceManager_RandInt(6))
		{
		case 0:
			{
				ResourceDescription *resource_description;

				DynamicMemoryStream resource_stream;				
				ResourceManager_GenerateStream(&resource_stream, i);

				resource_description = ResourceManager::Instance->AddResource(
					ResourceManager_GenerateName(i),
					i % 10,
					&resource_stream,
					(i % 5 == 0) ? 
						ResourceDescription::Preload : 
						ResourceDescription::NoAttributes
				);
				Check_Object(resource_description);
			}
			break;

		case 1:
			{
				ResourceDescription *resource_description, *resource_description2;
				
				int j = ResourceManager_RandInt(ResourceManager::Instance->GetResourceCount());
				MString resource_name = ResourceManager_GenerateName(j);
				ResourceType type = j % 10;
				
				DynamicMemoryStream resource_stream;
				ResourceManager_GenerateStream(&resource_stream, j);

				resource_description = ResourceManager::Instance->GetResource(
					resource_name,
					type
				);
				if (resource_description != NULL)
				{
					Check_Object(resource_description);
					
					resource_description->Lock();
					Verify(resource_description->recordName == resource_name);
					Verify(resource_description->recordType == type);		
					ResourceManager_CompareStream(
						&resource_stream, 
						resource_description->recordData
					);
					// resource_description->Unlock();

					resource_description2 = ResourceManager::Instance->GetResource(
						resource_description->resourceID
					);
					Verify(resource_description2 == resource_description);
					Verify(resource_description->IsLocked());
				}
			}
			break;

		case 2:
			{
				ResourceDescription *resource_description;

				int j = ResourceManager_RandInt(i);
				MString resource_name = ResourceManager_GenerateName(j);
				ResourceType type = j % 10;
				
				resource_description = ResourceManager::Instance->GetResource(
					resource_name,
					type
				);
				if (
					resource_description != NULL &&
					resource_description->IsLocked()
				)
				{
					Check_Object(resource_description);
					resource_description->Unlock();
				}
			}
			break;

		case 3:
			{
				ResourceDescription *resource_description;
				
				int j = ResourceManager_RandInt(i);
				MString resource_name = ResourceManager_GenerateName(j);
				ResourceType type = j % 10;
				
				resource_description = ResourceManager::Instance->GetResource(
					resource_name,
					type
				);
				if (resource_description != NULL)
				{
					PlugLocker locker(resource_description);
				}
			}
			break;

		case 4:
			{
				ResourceDescription *resource_description;
				
				int j = ResourceManager_RandInt(i);
				MString resource_name = ResourceManager_GenerateName(j);
				ResourceType type = j % 10;
				
				resource_description = ResourceManager::Instance->GetResource(
					resource_name,
					type
				);
				if (resource_description != NULL)
				{
					resource_description->Save();
				}
			}
			break;

		case 5:
			{
				ResourceDescription *resource_description;
				
				int j = ResourceManager_RandInt(i);
				MString resource_name = ResourceManager_GenerateName(j);
				ResourceType type = j % 10;
				
				resource_description = ResourceManager::Instance->GetResource(
					resource_name,
					type
				);
				if (
					resource_description != NULL &&
					!resource_description->IsLocked()
				)
				{
					resource_description->Delete();
				}
			}
			break;
		}
	}

	//
	// Exercise preload routines
	//
	ResourceManager::Instance->BuildPreloadList();
	ResourceManager::Instance->Preload();

	//
	// Close
	//
	ResourceManager::Instance->Close(true, true);
#endif
}
