/**
 * Copyright 2022-2025 Theai, Inc. dba Inworld AI
 */

#include "Audio/InworldAudioCapture_MasterSubmix.h"

#include "AudioMixerDevice.h"
#include "AudioMixerSubmix.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "InworldRuntime.h"

void FInworldAudioCapture_MasterSubmix::StartCapture()
{
	if (UWorld * World{Owner.IsValid() ? Owner->GetWorld() : nullptr}; World != nullptr)
	{
		if (Audio::FMixerDevice * MixerDevice{static_cast<Audio::FMixerDevice*>(World->GetAudioDeviceRaw())};
			MixerDevice != nullptr)
		{
			if (Audio::FMixerSubmixWeakPtr MasterSubmixWeakPtr{MixerDevice->GetMasterSubmix()}; MasterSubmixWeakPtr.IsValid())
			{
				MasterSubmixWeakPtr.Pin()->RegisterBufferListener(
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION < 4
					this
#else
					AsShared()
#endif
				);
				RegisteredDeviceId = MixerDevice->DeviceID;
			}
		}
	}
}

void FInworldAudioCapture_MasterSubmix::StopCapture()
{
	if (FAudioDeviceManager * AudioDeviceManager{GEngine ? GEngine->GetAudioDeviceManager() : nullptr};
		AudioDeviceManager != nullptr)
	{
		if (Audio::FMixerDevice *
				MixerDevice{static_cast<Audio::FMixerDevice*>(AudioDeviceManager->GetAudioDeviceRaw(RegisteredDeviceId))};
			MixerDevice != nullptr)
		{
			if (Audio::FMixerSubmixWeakPtr MasterSubmixWeakPtr{MixerDevice->GetMasterSubmix()}; MasterSubmixWeakPtr.IsValid())
			{
				MasterSubmixWeakPtr.Pin()->UnregisterBufferListener(
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION < 4
					this
#else
					AsShared()
#endif
				);
				RegisteredDeviceId = INDEX_NONE;
			}
		}
	}
}

void FInworldAudioCapture_MasterSubmix::SetCaptureDeviceById(const FString& DeviceId)
{
	UE_LOG(LogInworldRuntime, Warning, TEXT("Cannot SetCaptureDeviceById for FInworldAudioCapture_MasterSubmix."));
}

void FInworldAudioCapture_MasterSubmix::OnNewSubmixBuffer(const USoundSubmix* OwningSubmix, float* AudioData, int32 NumSamples,
	int32 NumChannels, const int32 SampleRate, double AudioClock)
{
	AudioDataCallback(FInworldAudioCaptureData{TArray<float>(AudioData, NumSamples), NumChannels, SampleRate});
}
