#include "RuntimeStateJson.h"

#include <iostream>
#include <string>
#include <vector>

namespace
{
int gFailures = 0;

void ExpectContains(const std::string& text, const std::string& fragment, const std::string& message)
{
	if (text.find(fragment) != std::string::npos)
		return;

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

ShaderPackage MakePackage()
{
	ShaderPackage package;
	package.id = "solid-color";
	package.displayName = "Solid Color";
	package.description = "A single color shader.";
	package.category = "Generator";

	ShaderPassDefinition pass;
	pass.id = "main";
	package.passes.push_back(pass);

	ShaderParameterDefinition color;
	color.id = "color";
	color.label = "Color";
	color.description = "Output color.";
	color.type = ShaderParameterType::Color;
	color.defaultNumbers = { 1.0, 0.25, 0.5, 1.0 };
	color.minNumbers = { 0.0, 0.0, 0.0, 0.0 };
	color.maxNumbers = { 1.0, 1.0, 1.0, 1.0 };
	color.stepNumbers = { 0.01, 0.01, 0.01, 0.01 };
	package.parameters.push_back(color);
	return package;
}
}

int main()
{
	RenderCadenceCompositor::AppConfig config = RenderCadenceCompositor::DefaultAppConfig();
	config.outputVideoFormat = "1080p";
	config.outputFrameRate = "59.94";

	RenderCadenceCompositor::CadenceTelemetrySnapshot telemetry;
	telemetry.renderFps = 59.94;
	telemetry.shaderBuildsCommitted = 1;

	std::vector<RenderCadenceCompositor::SupportedShaderSummary> shaders = {
		{ "solid-color", "Solid Color", "A single color shader.", "Generator" }
	};
	const ShaderPackage package = MakePackage();

	const std::string json = RenderCadenceCompositor::RuntimeStateToJson(RenderCadenceCompositor::RuntimeStateJsonInput{
		config,
		telemetry,
		8080,
		true,
		"DeckLink scheduled output running.",
		shaders,
		true,
		"Runtime shader committed.",
		&package
	});

	ExpectContains(json, "\"shaders\":[{\"id\":\"solid-color\"", "state JSON should include supported shaders");
	ExpectContains(json, "\"layerCount\":1", "state JSON should expose the display layer count");
	ExpectContains(json, "\"layers\":[{\"id\":\"runtime-layer-1\"", "state JSON should expose the active display layer");
	ExpectContains(json, "\"parameters\":[{\"id\":\"color\"", "state JSON should expose active shader parameters");
	ExpectContains(json, "\"type\":\"color\"", "state JSON should serialize parameter types for the UI");
	ExpectContains(json, "\"width\":1920", "state JSON should expose output width");
	ExpectContains(json, "\"height\":1080", "state JSON should expose output height");

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

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