#include "munga.h"
#pragma hdrstop

#include "evtstat.h"
#include "app.h"
#include "registry.h"
#include "entity.h"

//#############################################################################
//##########################    EventStatistics    ############################
//#############################################################################

//
//#############################################################################
//#############################################################################
//
EventStatistics::EventStatistics(
	ClassID class_ID,
	Receiver::MessageID message_ID
):
	classID(class_ID),
	messageID(message_ID),
	eventCount(0)
{
}

//#############################################################################
//########################    EventStatisticsManager    #######################
//#############################################################################

EventStatisticsManager 
	event_statistics_manager;

//
//#############################################################################
//#############################################################################
//
EventStatisticsManager::EventStatisticsManager():
	eventStatisticsSocket(NULL, True)
{
	printedReport = False;
}

//
//#############################################################################
//#############################################################################
//
void
	EventStatisticsManager::Maintain(Event *event)
{
	Check(this);
	Check(event);
	
	//
	// If the application is not running then it is not time to collect
	// statistics yet
	//
	Check(application);
	if (application->GetApplicationState() != Application::RunningMission)
		return;

	//
	// Add statistics for this event
	//
	ClassID 
		class_ID;
	Receiver::MessageID 
		message_ID;
	long 
		index_value;
	EventStatistics 
		*event_statistics;
	
	message_ID = event->messageToSend->messageID;
	class_ID = event->targetReceiver.GetCurrent()->GetClassID();
	index_value = class_ID * 1000 + message_ID; // HACK to create unique key
	if ((event_statistics = eventStatisticsSocket.Find(index_value)) == NULL)
	{
		event_statistics = new EventStatistics(class_ID, message_ID);
		eventStatisticsSocket.AddValue(event_statistics, index_value);
	}
	Check(event_statistics);
	event_statistics->eventCount++;
}

//
//#############################################################################
//#############################################################################
//
void
	EventStatisticsManager::Report()
{
	Check(this);
	
	//
	// Print Report
	//
	TableIteratorOf<EventStatistics*, long>
		iterator(&eventStatisticsSocket);
	EventStatistics
		*event_statistics;

	std::cout << "EventStatisticsManager::Report - event_count="
		<< iterator.GetSize() << "\n";
	while ((event_statistics = iterator.ReadAndNext()) != NULL)
	{
		Check(event_statistics);
		
		Registry
			*registry;
		Entity::SharedData
			*shared_data;
		Derivation
			*derivation;
		Receiver::MessageHandlerSet
			*handlers;

		std::cout << "EventStatisticsManager::Report -\t";
		std::cout << event_statistics->classID << "\t";
		std::cout << event_statistics->messageID << "\t";
		std::cout << event_statistics->eventCount << "\t";

		Check(application);
		if ((registry = application->GetRegistry()) != NULL)
		{
			Check(registry);
			shared_data = registry->GetStaticData(event_statistics->classID);			
			if (shared_data != NULL)
			{
				Check(shared_data);
				derivation = shared_data->derivedClasses;
				Check(derivation);
				handlers = shared_data->activeMessageHandlers;
				Check(handlers);

				std::cout << derivation->className << "::"
					<< handlers->GetName(event_statistics->messageID) << "\t";				
			}
		}
		std::cout << "\n";
	}
	iterator.DeletePlugs();
}
