#ifndef _LIVOX_GEN1_PCLOUD_AMBIENCE_STIMULUS_BUFFER_H
#define _LIVOX_GEN1_PCLOUD_AMBIENCE_STIMULUS_BUFFER_H

#include <memory>
#include <cstdint>
#include <list>
#include <cstddef>
#include <vector>
#include <string>
#include <user/stimulusBuffer.h>
#include <user/stagingBuffer.h>
#include <user/deviceAttachmentSpec.h>
#include "lg1PcloudAmbienceStencil.h"

namespace smo {
namespace stim_buff {

// Forward declaration
class StimulusProducer;

/**
 * PcloudAmbienceStimulusBuffer is a specialized StimulusBuffer for ambience point cloud data.
 */
class PcloudAmbienceStimulusBuffer
:	public StimulusBuffer
{
public:
	explicit PcloudAmbienceStimulusBuffer(
		StimulusProducer& parent,
		const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
		int histbuffMs,
		const StagingBuffer::IOEngineConstraints& inputEngineConstraints,
		const StagingBuffer::IOEngineConstraints& outputEngineConstraints,
		const SmoCallbacks& callbacks,
		cl_mem_flags flags,
		size_t nStencils_, size_t nDgramsPerFrame_)
	:	StimulusBuffer(
			parent, deviceAttachmentSpec, histbuffMs,
			inputEngineConstraints, outputEngineConstraints,
			callbacks, flags),
	nStencils(nStencils_)
	{
		// Parse postrinInterestPercentage (interpreted as percentage 0-100)
		const std::vector<std::string> postrinInterestThresholdParamNames = {
			"postrin-interest-percentage",
			"postrin-interest-pc",
			"postrin-interest"
		};

		postrinInterestPercentage = static_cast<uint32_t>(
			device::DeviceAttachmentSpec::parseOptionalParamAsIntWithSynonyms(
				deviceAttachmentSpec->qualeIfaceApiParams,
				postrinInterestThresholdParamNames,
				90));

		// Convert percentage to absolute frame count
		postrinInterestThreshold = static_cast<uint32_t>(
			(nDgramsPerFrame_ * postrinInterestPercentage) / 100);
		// Parse ambienceIntensityLowVal from qualeIfaceApiParams
		const std::vector<std::string> ambienceIntensityLowValParamNames = {
			"ambience-intensity-low-val"
		};
		ambienceIntensityLowVal = static_cast<uint32_t>(
			device::DeviceAttachmentSpec::parseOptionalParamAsIntWithSynonyms(
				deviceAttachmentSpec->qualeIfaceApiParams,
				ambienceIntensityLowValParamNames, 8));

		// Construct stencils and add to list (FIFO behavior)
		for (size_t i = 0; i < nStencils; ++i) {
			stencils.emplace_back();
		}
	}

	~PcloudAmbienceStimulusBuffer() = default;

	// Non-copyable, movable
	PcloudAmbienceStimulusBuffer(const PcloudAmbienceStimulusBuffer&) = delete;
	PcloudAmbienceStimulusBuffer& operator=(const PcloudAmbienceStimulusBuffer&) = delete;
	PcloudAmbienceStimulusBuffer(PcloudAmbienceStimulusBuffer&&) = default;
	PcloudAmbienceStimulusBuffer& operator=(PcloudAmbienceStimulusBuffer&&) = default;

public:
	uint32_t postrinInterestPercentage;
	uint32_t postrinInterestThreshold;
	uint32_t ambienceIntensityLowVal;
	size_t nStencils;
	std::list<LG1PcloudAmbienceStencil> stencils;
};

} // namespace stim_buff
} // namespace smo

#endif // _LIVOX_GEN1_PCLOUD_AMBIENCE_STIMULUS_BUFFER_H
