#ifndef _LIVOX_GEN1_PCLOUD_FRAME_DUMPER_H
#define _LIVOX_GEN1_PCLOUD_FRAME_DUMPER_H

#include <filesystem>
#include <memory>
#include <string>
#include <livoxProto1/device.h>
#include <spinscale/asynchronousLoop.h>
#include <user/deviceAttachmentSpec.h>
#include <user/stagingBuffer.h>

namespace smo {
namespace stim_buff {

class LivoxPcloudFrameDumper
{
public:
	explicit LivoxPcloudFrameDumper(
		const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec);
	~LivoxPcloudFrameDumper() = default;

	LivoxPcloudFrameDumper(const LivoxPcloudFrameDumper&) = delete;
	LivoxPcloudFrameDumper& operator=(const LivoxPcloudFrameDumper&) = delete;
	LivoxPcloudFrameDumper(LivoxPcloudFrameDumper&&) = delete;
	LivoxPcloudFrameDumper& operator=(LivoxPcloudFrameDumper&&) = delete;

	bool isEnabled() const { return enabled; }
	void prepareForRun() const;
	void dumpProducedFrame(
		const livoxProto1::Device& device,
		const StagingBuffer& collationBuffer,
		const sscl::AsynchronousLoop& frameAssemblyResult) const;

private:
	static std::string parseDumpDirParam(
		const std::vector<std::pair<std::string, std::string>>& params);
	static std::filesystem::path resolveDumpDirectory(
		const std::string& dumpDirParam);
	static std::string makeTimestampStem(const std::string& deviceSelector);
	static std::filesystem::path makeUniqueFramePath(
		const std::filesystem::path& dumpDir,
		const std::string& deviceSelector);
	static void writeBinaryPcdFile(
		const std::filesystem::path& outputPath,
		const StagingBuffer& collationBuffer,
		std::size_t nSucceeded,
		std::size_t pointsPerDgram);

private:
	bool enabled;
	std::string deviceSelector;
	std::filesystem::path dumpDirectory;
};

} // namespace stim_buff
} // namespace smo

#endif // _LIVOX_GEN1_PCLOUD_FRAME_DUMPER_H
