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

#pragma once

#include "CoreMinimal.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Paths.h"

THIRD_PARTY_INCLUDES_START
#include <string>
THIRD_PARTY_INCLUDES_END

namespace inworld
{
class Device;
enum class DeviceType;
}	 // namespace inworld

/**
 * @class FInworldRuntimeUtils
 * @brief Utility functions for Inworld Runtime operations.
 *
 * This struct provides static utility functions for common operations in the
 * Inworld Runtime system, including device management, phoneme-to-viseme
 * conversion, and object serialization/deserialization.
 */
struct INWORLDRUNTIME_API FInworldRuntimeUtils
{
	/**
	 * @brief Attempts to retrieve the requested device type, defaulting to CPU if unavailable.
	 * @param device_type The type of device to retrieve.
	 * @return The device instance corresponding to the requested type.
	 */
	static inworld::Device GetDevice(inworld::DeviceType device_type);

	/**
	 * @brief Converts a phoneme string to its corresponding viseme representation.
	 * @param Phoneme The phoneme string to convert.
	 * @return The viseme string corresponding to the input phoneme.
	 */
	static std::string PhonemeToViseme(const std::string& Phoneme);

	/**
	 * @brief Serializes a UObject instance to a string representation.
	 * @param Instance The UObject instance to serialize.
	 * @return A string representation of the serialized object.
	 */
	static FString SerializeInstance(UObject* Instance);

	/**
	 * @brief Deserializes a string representation back into a UObject instance.
	 * @param Instance The UObject instance to populate with deserialized data.
	 * @param InstanceData The string data to deserialize.
	 */
	static void DeserializeInstance(UObject* Instance, const FString& InstanceData);
};

template <typename... Args>
FORCEINLINE FString GetInworldExtrasPath(Args&&... args)
{
	const FString PluginBaseDir{IPluginManager::Get().FindPlugin(TEXT("InworldRuntime"))->GetBaseDir()};
	return FPaths::Combine(PluginBaseDir, "Extras", Forward<Args>(args)...);
}

INWORLDRUNTIME_API const FString& GetInworldPluginVersion();
INWORLDRUNTIME_API const FString& GetInworldRuntimeApiKey();
