class_name M2RawModelRepository
extends RefCounted

## Reads raw static and animated M2 Dictionaries through the optional native
## M2Loader boundary. The repository is stateless and does not cache failures.

const NATIVE_LOADER_CLASS_NAME := "M2Loader"


## Loads one normalized static M2 path with the native `load_m2` method.
## Invalid input, unavailable native support and parse failures return `{}`.
func load_static_model_data(
		extracted_directory: String,
		normalized_relative_path: String) -> Dictionary:
	return _load_model_data(
		extracted_directory,
		normalized_relative_path,
		"load_m2"
	)


## Loads one normalized animated M2 path with the native `load_m2_animated`
## method. Invalid input, unavailable support and parse failures return `{}`.
func load_animated_model_data(
		extracted_directory: String,
		normalized_relative_path: String) -> Dictionary:
	return _load_model_data(
		extracted_directory,
		normalized_relative_path,
		"load_m2_animated"
	)


func _load_model_data(
		extracted_directory: String,
		normalized_relative_path: String,
		native_method_name: StringName) -> Dictionary:
	if normalized_relative_path.is_empty():
		return {}
	if not ClassDB.class_exists(NATIVE_LOADER_CLASS_NAME):
		return {}
	var absolute_path := ProjectSettings.globalize_path(
		extracted_directory.path_join(normalized_relative_path)
	)
	if not FileAccess.file_exists(absolute_path):
		return {}
	var native_loader: Object = ClassDB.instantiate(NATIVE_LOADER_CLASS_NAME)
	if native_loader == null or not native_loader.has_method(native_method_name):
		return {}
	var raw_model_data: Variant = native_loader.call(native_method_name, absolute_path)
	return raw_model_data if raw_model_data is Dictionary else {}
