/*
 * Copyright 2025 Holo-Light GmbH. All Rights Reserved.
 */

#ifndef HOLOLIGHT_UNREAL_FSTREAMAUDIOLISTENER_H
#define HOLOLIGHT_UNREAL_FSTREAMAUDIOLISTENER_H

#include "StreamHMDCommon.h"

#include "ISubmixBufferListener.h"

#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>


/// <summary>
/// Implements the Unreal Engine Submix Buffer Listener interface, which can be subscribed to the engine for listening
/// the audio generated by the game. This class is responsible of receiving the audio, queueing the audio data
/// into a buffer and sending the data to the Server API in required sample rate.
/// </summary>
class FStreamAudioListener : public ISubmixBufferListener
{
public:
	FStreamAudioListener();
	~FStreamAudioListener() override;

	void SetStreamApi(isar::IsarConnection connection, isar::IsarServerApi* serverApi);
	void SetConnected(bool connected);

	// ISubmixBufferListener interface
	void OnNewSubmixBuffer(const USoundSubmix* owningSubmix, float* audioData, int32 numSamples,
								   int32 numChannels, const int32 sampleRate, double audioClock) override;

	static constexpr int MAX_NUM_CHANNELS = 2;
	static constexpr int SAMPLE_RATE = 48000;
	static constexpr int BUFFER_SIZE = 480;
	static constexpr int BITS_PER_SAMPLE = 16;

private:
	bool m_connected;
	isar::IsarConnection m_streamConnection;
	isar::IsarServerApi* m_serverApi;

	int m_numChannels = 2;

	// Upon trials, it is seen that TArray is safe for removing from the beginning and appending to the end on different
	// threads without a mutex, and usage of a mutex creates issues with audio timings
	TArray<int16_t> m_carryBuffer;

	std::thread m_pushThread;
	std::atomic<bool> m_isRunning;
	std::mutex m_newDataMutex;
	std::condition_variable m_newDataCv;

	void PushCarryBuffer();
};

#endif // HOLOLIGHT_UNREAL_FSTREAMAUDIOLISTENER_H