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

#pragma once

#include "CoreMinimal.h"
#include "Graph/InworldProcessContext.h"
#include "Graph/Nodes/InworldNode_Custom.h"

#include "InworldNode_GetRuntimeData.generated.h"

/**
 * @enum EInworldGetRuntimeDataType
 * @brief Enumeration of supported data types for runtime data retrieval.
 */
UENUM(BlueprintType)
enum class EInworldGetRuntimeDataType : uint8
{
	/** Structure data type */
	STRUCT UMETA(DisplayName = "Struct"),
	/** Object reference data type */
	OBJECT UMETA(DisplayName = "Object"),
	/** Boolean data type */
	BOOL UMETA(DisplayName = "Boolean"),
	/** Integer data type */
	INT UMETA(DisplayName = "Integer"),
	/** Float data type */
	FLOAT UMETA(DisplayName = "Float"),
};

/**
 * @class UInworldNode_GetRuntimeData
 * @brief Node that retrieves runtime data from the process context.
 *
 * This getter node allows access to runtime data stored in the process context
 * during graph execution. It can retrieve various data types including structs,
 * objects, and primitive values by their key identifier.
 *
 * @output FInworldDataHandle - The requested runtime data wrapped in a data handle
 */
UCLASS()
class INWORLDRUNTIME_API UInworldNode_GetRuntimeData : public UInworldNode_Custom
{
	GENERATED_BODY()

public:
	/**
	 * @brief Default constructor for the get runtime data node.
	 *
	 * Initializes the node with appropriate settings for runtime data retrieval,
	 * including marking it as a getter node and configuring thread execution preferences.
	 */
	UInworldNode_GetRuntimeData()
	{
		NodeName = "Get Runtime Data";
		bIsGetter = true;
		bExecuteProcessInGameThread = false;
	}

	/**
	 * @brief Processes the runtime data retrieval request.
	 *
	 * This function handles the actual retrieval of runtime data from the process context
	 * based on the configured key and data type settings.
	 *
	 * @param ProcessContext The process context containing runtime data
	 * @return Handle to the retrieved runtime data
	 */
	UFUNCTION()
	FInworldDataHandle Process_GetRuntimeData(UInworldProcessContext* ProcessContext);

	/** The key identifier for the runtime data to retrieve */
	UPROPERTY(EditDefaultsOnly, Category = "Inworld", Meta = (ToolTip = "The key identifier for the runtime data to retrieve"))
	FName RuntimeDataKey;

	/** The expected data type of the runtime data to retrieve */
	UPROPERTY(EditDefaultsOnly, Category = "Inworld", Meta = (ToolTip = "The expected data type of the runtime data to retrieve"))
	EInworldGetRuntimeDataType DataType{EInworldGetRuntimeDataType::STRUCT};

	/** The struct type to expect when DataType is STRUCT */
	UPROPERTY(EditDefaultsOnly, Category = "Inworld",
		Meta = (EditCondition = "DataType==EInworldGetRuntimeDataType::STRUCT", EditConditionHides,
			ToolTip = "The struct type to expect when DataType is STRUCT"))
	UScriptStruct* StructType;

	/** The object class to expect when DataType is OBJECT */
	UPROPERTY(EditDefaultsOnly, Category = "Inworld",
		Meta = (EditCondition = "DataType==EInworldGetRuntimeDataType::OBJECT", EditConditionHides,
			ToolTip = "The object class to expect when DataType is OBJECT"))
	TSubclassOf<UObject> ObjectType;

	UFUNCTION(BlueprintCallable, Category = "Inworld")
	FString GetRuntimeDataClassName();
};
