#include "EmoShapeSubSystem/EmoShapeWebUtility/Public/ESMeasureTimer.h"
#include "Containers/UnrealString.h"
#include "HAL/PlatformTime.h"

#if ENABLE_EMOSHAPE_PRECISE_TIMER
static TMap<FString, TSharedPtr<FESMeasureTimer>> FPreciseTimerInternalMap;
#endif

void FESMeasureTimer::Tick(const FString& LogMsg /*= TEXT("TimeTaken")*/)
{
#if ENABLE_EMOSHAPE_PRECISE_TIMER
	TSharedPtr<FESMeasureTimer> Timer = MakeShareable(new FESMeasureTimer);
	FPreciseTimerInternalMap.Add(LogMsg, Timer);
	Timer->Then = FPlatformTime::Seconds();	//start timer last so we don't measure anything else
	#endif
}

double FESMeasureTimer::Tock(const FString& LogMsg /*= TEXT("TimeTaken")*/, bool bShouldLogResult /*= true*/)
{
#if ENABLE_EMOSHAPE_PRECISE_TIMER
	double Now = FPlatformTime::Seconds();
	if (!FPreciseTimerInternalMap.Contains(LogMsg))
	{
		UE_LOG(LogTemp, Warning, TEXT("FEmoShapeMeasureTimer::Tock error: <%s> no such category ticked."), *LogMsg);
		return 0.0;
	}
	TSharedPtr<FESMeasureTimer> Timer = FPreciseTimerInternalMap[LogMsg];
	double Elapsed = (Now - Timer->Then) * 1000.0;
	if (bShouldLogResult)
	{
		UE_LOG(LogTemp, Log, TEXT("%s %1.3f ms"), *LogMsg, Elapsed);
	}
	FPreciseTimerInternalMap.Remove(LogMsg);
#else
	return 0.0;
#endif
	return Elapsed;
}

FESScopeTimer::FESScopeTimer(const FString& LogMsg)
{
	LogMessage = LogMsg;
	FESMeasureTimer::Tick(LogMsg);
}

FESScopeTimer::~FESScopeTimer()
{
	FESMeasureTimer::Tock(LogMessage);
}
