// Georgy Treshchev 2025.

#pragma once

#include "CoreMinimal.h"
#include "ILipSyncProcessor.h"
#include "UObject/Object.h"
#include "Templates/Function.h"
#include "Containers/Map.h"
#include "Templates/SharedPointer.h"
#include "UObject/WeakObjectPtr.h"
#include "UObject/WeakObjectPtrTemplates.h"
#include "HAL/CriticalSection.h"
#include "OVRLipSyncContextWrapper.h"

/**
 * Default implementation of ILipSyncProcessor
 */
class RUNTIMEMETAHUMANLIPSYNC_STANDARD_API FDefaultLipSyncProcessor : public ILipSyncProcessor
{
public:
	FDefaultLipSyncProcessor();
	virtual ~FDefaultLipSyncProcessor() override;

	// ILipSyncProcessor interface
	virtual void Initialize(UObject* ContextOwner, int32 SampleRate, int32 BufferSize) override;
	virtual void SetAsyncCallback(UObject* ContextOwner, TFunction<void(const TArray<float>&, float)> Callback) override;
	virtual void ProcessFrameAsync(UObject* ContextOwner, const float* PCMData, int32 NumSamples) override;
	virtual void CleanupContext(UObject* ContextOwner) override;
    
private:
	struct FLipSyncContextData
	{
#if PLATFORM_WINDOWS || PLATFORM_ANDROID
		TSharedPtr<UOVRLipSyncContextWrapper> LipSyncContext;
#endif
		TFunction<void(const TArray<float>&, float)> CallbackFunction;
	};

	// Map from context owner to lip sync context data
	TMap<TWeakObjectPtr<UObject>, TSharedPtr<FLipSyncContextData>> ContextMap;
	
	// Mutex to protect the context map for thread safety
	mutable FCriticalSection ContextMapMutex;
	
	// Helper function to get or create context data
	TSharedPtr<FLipSyncContextData> GetOrCreateContextData(UObject* ContextOwner);
};