#include "SupportedShaderCatalog.h"

#include <iostream>
#include <string>

namespace
{
int gFailures = 0;

void Expect(bool condition, const std::string& message)
{
	if (condition)
		return;

	++gFailures;
	std::cerr << "FAIL: " << message << "\n";
}

ShaderPackage MakeSinglePassPackage()
{
	ShaderPackage shaderPackage;
	shaderPackage.id = "supported";
	ShaderPassDefinition pass;
	pass.id = "main";
	pass.entryPoint = "mainImage";
	shaderPackage.passes.push_back(pass);
	return shaderPackage;
}

void SupportsSinglePassStatelessPackage()
{
	const ShaderPackage shaderPackage = MakeSinglePassPackage();
	const RenderCadenceCompositor::ShaderSupportResult result =
		RenderCadenceCompositor::CheckStatelessSinglePassShaderSupport(shaderPackage);

	Expect(result.supported, "single-pass stateless packages should be supported");
	Expect(result.reason.empty(), "supported packages should not report a rejection reason");
}

void RejectsMultipassPackage()
{
	ShaderPackage shaderPackage = MakeSinglePassPackage();
	ShaderPassDefinition secondPass;
	secondPass.id = "second";
	secondPass.entryPoint = "mainImage";
	shaderPackage.passes.push_back(secondPass);

	const RenderCadenceCompositor::ShaderSupportResult result =
		RenderCadenceCompositor::CheckStatelessSinglePassShaderSupport(shaderPackage);

	Expect(!result.supported, "multipass packages should be rejected");
	Expect(result.reason.find("single-pass") != std::string::npos, "multipass rejection should explain the single-pass limit");
}

void RejectsTemporalPackage()
{
	ShaderPackage shaderPackage = MakeSinglePassPackage();
	shaderPackage.temporal.enabled = true;

	const RenderCadenceCompositor::ShaderSupportResult result =
		RenderCadenceCompositor::CheckStatelessSinglePassShaderSupport(shaderPackage);

	Expect(!result.supported, "temporal packages should be rejected");
	Expect(result.reason.find("temporal") != std::string::npos, "temporal rejection should mention temporal storage");
}

void RejectsTextureAssets()
{
	ShaderPackage shaderPackage = MakeSinglePassPackage();
	ShaderTextureAsset asset;
	asset.id = "lut";
	shaderPackage.textureAssets.push_back(asset);

	const RenderCadenceCompositor::ShaderSupportResult result =
		RenderCadenceCompositor::CheckStatelessSinglePassShaderSupport(shaderPackage);

	Expect(!result.supported, "texture-backed packages should be rejected for now");
	Expect(result.reason.find("texture") != std::string::npos, "texture rejection should mention texture assets");
}

void RejectsTextParameters()
{
	ShaderPackage shaderPackage = MakeSinglePassPackage();
	ShaderParameterDefinition parameter;
	parameter.id = "caption";
	parameter.type = ShaderParameterType::Text;
	shaderPackage.parameters.push_back(parameter);

	const RenderCadenceCompositor::ShaderSupportResult result =
		RenderCadenceCompositor::CheckStatelessSinglePassShaderSupport(shaderPackage);

	Expect(!result.supported, "text-parameter packages should be rejected for now");
	Expect(result.reason.find("text") != std::string::npos, "text rejection should mention text parameters");
}
}

int main()
{
	SupportsSinglePassStatelessPackage();
	RejectsMultipassPackage();
	RejectsTemporalPackage();
	RejectsTextureAssets();
	RejectsTextParameters();

	if (gFailures != 0)
	{
		std::cerr << gFailures << " RenderCadenceCompositorSupportedShaderCatalog test failure(s).\n";
		return 1;
	}

	std::cout << "RenderCadenceCompositorSupportedShaderCatalog tests passed.\n";
	return 0;
}
