#include "stdafx.h"
#include "ShaderManifestParser.h"

namespace ShaderManifestParsing
{
bool ParseTextureAssets(const JsonValue& manifestJson, ShaderPackage& shaderPackage, const std::filesystem::path& manifestPath, std::string& error)
{
	const JsonValue* texturesValue = nullptr;
	if (!OptionalArrayField(manifestJson, "textures", texturesValue, manifestPath, error))
		return false;
	if (!texturesValue)
		return true;

	for (const JsonValue& textureJson : texturesValue->asArray())
	{
		if (!textureJson.isObject())
		{
			error = "Shader texture entry must be an object in: " + ManifestPathMessage(manifestPath);
			return false;
		}

		std::string textureId;
		std::string texturePath;
		if (!RequireNonEmptyStringField(textureJson, "id", textureId, manifestPath, error) ||
			!RequireNonEmptyStringField(textureJson, "path", texturePath, manifestPath, error))
		{
			error = "Shader texture is missing required 'id' or 'path' in: " + ManifestPathMessage(manifestPath);
			return false;
		}
		if (!ValidateShaderIdentifier(textureId, "textures[].id", manifestPath, error))
			return false;

		ShaderTextureAsset textureAsset;
		textureAsset.id = textureId;
		textureAsset.path = shaderPackage.directoryPath / texturePath;
		if (!std::filesystem::exists(textureAsset.path))
		{
			error = "Shader texture asset not found for package " + shaderPackage.id + ": " + textureAsset.path.string();
			return false;
		}

		textureAsset.writeTime = std::filesystem::last_write_time(textureAsset.path);
		shaderPackage.textureAssets.push_back(textureAsset);
	}

	return true;
}

bool ParseFontAssets(const JsonValue& manifestJson, ShaderPackage& shaderPackage, const std::filesystem::path& manifestPath, std::string& error)
{
	const JsonValue* fontsValue = nullptr;
	if (!OptionalArrayField(manifestJson, "fonts", fontsValue, manifestPath, error))
		return false;
	if (!fontsValue)
		return true;

	for (const JsonValue& fontJson : fontsValue->asArray())
	{
		if (!fontJson.isObject())
		{
			error = "Shader font entry must be an object in: " + ManifestPathMessage(manifestPath);
			return false;
		}

		std::string fontId;
		std::string fontPath;
		if (!RequireNonEmptyStringField(fontJson, "id", fontId, manifestPath, error) ||
			!RequireNonEmptyStringField(fontJson, "path", fontPath, manifestPath, error))
		{
			error = "Shader font is missing required 'id' or 'path' in: " + ManifestPathMessage(manifestPath);
			return false;
		}
		if (!ValidateShaderIdentifier(fontId, "fonts[].id", manifestPath, error))
			return false;

		ShaderFontAsset fontAsset;
		fontAsset.id = fontId;
		fontAsset.path = shaderPackage.directoryPath / fontPath;
		if (!std::filesystem::exists(fontAsset.path))
		{
			error = "Shader font asset not found for package " + shaderPackage.id + ": " + fontAsset.path.string();
			return false;
		}

		fontAsset.writeTime = std::filesystem::last_write_time(fontAsset.path);
		shaderPackage.fontAssets.push_back(fontAsset);
	}

	return true;
}
}
