/*
 * Copyright 2018 Bradley Austin Davis
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "spirv_reflect.hpp"
#include "spirv_glsl.hpp"
#include <iomanip>

using namespace spv;
using namespace spirv_cross;
using namespace std;

namespace simple_json
{
enum class Type
{
	Object,
	Array,
};

using State = std::pair<Type, bool>;
using Stack = std::stack<State>;

class Stream
{
	Stack stack;
	std::ostringstream buffer;
	uint32_t indent{ 0 };

public:
	void begin_json_object();
	void end_json_object();
	void emit_json_key(const std::string &key);
	void emit_json_key_value(const std::string &key, const std::string &value);
	void emit_json_key_value(const std::string &key, bool value);
	void emit_json_key_value(const std::string &key, uint32_t value);
	void emit_json_key_value(const std::string &key, int32_t value);
	void emit_json_key_value(const std::string &key, float value);
	void emit_json_key_object(const std::string &key);
	void emit_json_key_array(const std::string &key);

	void begin_json_array();
	void end_json_array();
	void emit_json_array_value(const std::string &value);
	void emit_json_array_value(uint32_t value);

	std::string str() const
	{
		return buffer.str();
	}

private:
	inline void statement_indent()
	{
		for (uint32_t i = 0; i < indent; i++)
			buffer << "    ";
	}

	template <typename T>
	inline void statement_inner(T &&t)
	{
		buffer << std::forward<T>(t);
	}

	template <typename T, typename... Ts>
	inline void statement_inner(T &&t, Ts &&... ts)
	{
		buffer << std::forward<T>(t);
		statement_inner(std::forward<Ts>(ts)...);
	}

	template <typename... Ts>
	inline void statement(Ts &&... ts)
	{
		statement_indent();
		statement_inner(std::forward<Ts>(ts)...);
		buffer << '\n';
	}

	template <typename... Ts>
	void statement_no_return(Ts &&... ts)
	{
		statement_indent();
		statement_inner(std::forward<Ts>(ts)...);
	}
};
} // namespace simple_json

using namespace simple_json;

// Hackery to emit JSON without using nlohmann/json C++ library (which requires a
// higher level of compiler compliance than is required by SPIRV-Cross
void Stream::begin_json_array()
{
	if (!stack.empty() && stack.top().second)
	{
		statement_inner(",\n");
	}
	statement("[");
	++indent;
	stack.emplace(Type::Array, false);
}

void Stream::end_json_array()
{
	if (stack.empty() || stack.top().first != Type::Array)
		SPIRV_CROSS_THROW("Invalid JSON state");
	if (stack.top().second)
	{
		statement_inner("\n");
	}
	--indent;
	statement_no_return("]");
	stack.pop();
	if (!stack.empty())
	{
		stack.top().second = true;
	}
}

void Stream::emit_json_array_value(const std::string &value)
{
	if (stack.empty() || stack.top().first != Type::Array)
		SPIRV_CROSS_THROW("Invalid JSON state");

	if (stack.top().second)
		statement_inner(",\n");

	statement_no_return("\"", value, "\"");
	stack.top().second = true;
}

void Stream::emit_json_array_value(uint32_t value)
{
	if (stack.empty() || stack.top().first != Type::Array)
		SPIRV_CROSS_THROW("Invalid JSON state");
	if (stack.top().second)
		statement_inner(",\n");
	statement_no_return(std::to_string(value));
	stack.top().second = true;
}

void Stream::begin_json_object()
{
	if (!stack.empty() && stack.top().second)
	{
		statement_inner(",\n");
	}
	statement("{");
	++indent;
	stack.emplace(Type::Object, false);
}

void Stream::end_json_object()
{
	if (stack.empty() || stack.top().first != Type::Object)
		SPIRV_CROSS_THROW("Invalid JSON state");
	if (stack.top().second)
	{
		statement_inner("\n");
	}
	--indent;
	statement_no_return("}");
	stack.pop();
	if (!stack.empty())
	{
		stack.top().second = true;
	}
}

void Stream::emit_json_key(const std::string &key)
{
	if (stack.empty() || stack.top().first != Type::Object)
		SPIRV_CROSS_THROW("Invalid JSON state");

	if (stack.top().second)
		statement_inner(",\n");
	statement_no_return("\"", key, "\" : ");
	stack.top().second = true;
}

void Stream::emit_json_key_value(const std::string &key, const std::string &value)
{
	emit_json_key(key);
	statement_inner("\"", value, "\"");
}

void Stream::emit_json_key_value(const std::string &key, uint32_t value)
{
	emit_json_key(key);
	statement_inner(value);
}

void Stream::emit_json_key_value(const std::string &key, int32_t value)
{
	emit_json_key(key);
	statement_inner(value);
}

void Stream::emit_json_key_value(const std::string &key, float value)
{
	emit_json_key(key);
	statement_inner(value);
}

void Stream::emit_json_key_value(const std::string &key, bool value)
{
	emit_json_key(key);
	statement_inner(value ? "true" : "false");
}

void Stream::emit_json_key_object(const std::string &key)
{
	emit_json_key(key);
	statement_inner("{\n");
	++indent;
	stack.emplace(Type::Object, false);
}

void Stream::emit_json_key_array(const std::string &key)
{
	emit_json_key(key);
	statement_inner("[\n");
	++indent;
	stack.emplace(Type::Array, false);
}

void CompilerReflection::set_format(const std::string &format)
{
	if (format != "json")
	{
		SPIRV_CROSS_THROW("Unsupported format");
	}
}

string CompilerReflection::compile()
{
	// Force a classic "C" locale, reverts when function returns
	ClassicLocale classic_locale;

	// Move constructor for this type is broken on GCC 4.9 ...
	json_stream = std::make_shared<simple_json::Stream>();
	json_stream->begin_json_object();
	emit_entry_points();
	emit_types();
	emit_resources();
	emit_specialization_constants();
	json_stream->end_json_object();
	return json_stream->str();
}

void CompilerReflection::emit_types()
{
	bool emitted_open_tag = false;
	for (auto &id : ir.ids)
	{
		auto idType = id.get_type();
		if (idType == TypeType)
		{
			auto &type = id.get<SPIRType>();
			if (type.basetype == SPIRType::Struct && !type.pointer && type.array.empty())
			{
				emit_type(type, emitted_open_tag);
			}
		}
	}

	if (emitted_open_tag)
	{
		json_stream->end_json_object();
	}
}

void CompilerReflection::emit_type(const SPIRType &type, bool &emitted_open_tag)
{
	auto name = type_to_glsl(type);

	if (type.type_alias != 0)
		return;

	if (!emitted_open_tag)
	{
		json_stream->emit_json_key_object("types");
		emitted_open_tag = true;
	}
	json_stream->emit_json_key_object("_" + std::to_string(type.self));
	json_stream->emit_json_key_value("name", name);
	json_stream->emit_json_key_array("members");
	// FIXME ideally we'd like to emit the size of a structure as a
	// convenience to people parsing the reflected JSON.  The problem
	// is that there's no implicit size for a type.  It's final size
	// will be determined by the top level declaration in which it's
	// included.  So there might be one size for the struct if it's
	// included in a std140 uniform block and another if it's included
	// in a std430 uniform block.
	// The solution is to include *all* potential sizes as a map of
	// layout type name to integer, but that will probably require
	// some additional logic being written in this class, or in the
	// parent CompilerGLSL class.
	auto size = type.member_types.size();
	for (uint32_t i = 0; i < size; ++i)
	{
		emit_type_member(type, i);
	}
	json_stream->end_json_array();
	json_stream->end_json_object();
}

void CompilerReflection::emit_type_member(const SPIRType &type, uint32_t index)
{
	auto &membertype = get<SPIRType>(type.member_types[index]);
	json_stream->begin_json_object();
	auto name = to_member_name(type, index);
	// FIXME we'd like to emit the offset of each member, but such offsets are
	// context dependent.  See the comment above regarding structure sizes
	json_stream->emit_json_key_value("name", name);
	if (membertype.basetype == SPIRType::Struct)
	{
		json_stream->emit_json_key_value("type", "_" + std::to_string(membertype.self));
	}
	else
	{
		json_stream->emit_json_key_value("type", type_to_glsl(membertype));
	}
	emit_type_member_qualifiers(type, index);
	json_stream->end_json_object();
}

void CompilerReflection::emit_type_array(const SPIRType &type)
{
	if (!type.array.empty())
	{
		json_stream->emit_json_key_array("array");
		// Note that we emit the zeros here as a means of identifying
		// unbounded arrays.  This is necessary as otherwise there would
		// be no way of differentiating between float[4] and float[4][]
		for (const auto &value : type.array)
			json_stream->emit_json_array_value(value);
		json_stream->end_json_array();
	}
}

void CompilerReflection::emit_type_member_qualifiers(const SPIRType &type, uint32_t index)
{
	auto flags = combined_decoration_for_member(type, index);
	if (flags.get(DecorationRowMajor))
		json_stream->emit_json_key_value("row_major", true);

	auto &membertype = get<SPIRType>(type.member_types[index]);
	emit_type_array(membertype);
	auto &memb = ir.meta[type.self].members;
	if (index < memb.size())
	{
		auto &dec = memb[index];
		if (dec.decoration_flags.get(DecorationLocation))
			json_stream->emit_json_key_value("location", dec.location);
		if (dec.decoration_flags.get(DecorationOffset))
			json_stream->emit_json_key_value("offset", dec.offset);
	}
}

string CompilerReflection::execution_model_to_str(spv::ExecutionModel model)
{
	switch (model)
	{
	case spv::ExecutionModelVertex:
		return "vert";
	case spv::ExecutionModelTessellationControl:
		return "tesc";
	case ExecutionModelTessellationEvaluation:
		return "tese";
	case ExecutionModelGeometry:
		return "geom";
	case ExecutionModelFragment:
		return "frag";
	case ExecutionModelGLCompute:
		return "comp";
	default:
		return "???";
	}
}

// FIXME include things like the local_size dimensions, geometry output vertex count, etc
void CompilerReflection::emit_entry_points()
{
	auto entries = get_entry_points_and_stages();
	if (!entries.empty())
	{
		json_stream->emit_json_key_array("entryPoints");
		for (auto &e : entries)
		{
			json_stream->begin_json_object();
			json_stream->emit_json_key_value("name", e.name);
			json_stream->emit_json_key_value("mode", execution_model_to_str(e.execution_model));
			json_stream->end_json_object();
		}
		json_stream->end_json_array();
	}
}

void CompilerReflection::emit_resources()
{
	auto res = get_shader_resources();
	emit_resources("subpass_inputs", res.subpass_inputs);
	emit_resources("inputs", res.stage_inputs);
	emit_resources("outputs", res.stage_outputs);
	emit_resources("textures", res.sampled_images);
	emit_resources("separate_images", res.separate_images);
	emit_resources("separate_samplers", res.separate_samplers);
	emit_resources("images", res.storage_images);
	emit_resources("ssbos", res.storage_buffers);
	emit_resources("ubos", res.uniform_buffers);
	emit_resources("push_constants", res.push_constant_buffers);
	emit_resources("counters", res.atomic_counters);
}

void CompilerReflection::emit_resources(const char *tag, const vector<Resource> &resources)
{
	if (resources.empty())
	{
		return;
	}

	json_stream->emit_json_key_array(tag);
	for (auto &res : resources)
	{
		auto &type = get_type(res.type_id);
		auto typeflags = ir.meta[type.self].decoration.decoration_flags;
		auto &mask = get_decoration_bitset(res.id);

		// If we don't have a name, use the fallback for the type instead of the variable
		// for SSBOs and UBOs since those are the only meaningful names to use externally.
		// Push constant blocks are still accessed by name and not block name, even though they are technically Blocks.
		bool is_push_constant = get_storage_class(res.id) == StorageClassPushConstant;
		bool is_block = get_decoration_bitset(type.self).get(DecorationBlock) ||
		                get_decoration_bitset(type.self).get(DecorationBufferBlock);

		uint32_t fallback_id = !is_push_constant && is_block ? res.base_type_id : res.id;

		json_stream->begin_json_object();

		if (type.basetype == SPIRType::Struct)
		{
			json_stream->emit_json_key_value("type", "_" + std::to_string(res.base_type_id));
		}
		else
		{
			json_stream->emit_json_key_value("type", type_to_glsl(type));
		}

		json_stream->emit_json_key_value("name", !res.name.empty() ? res.name : get_fallback_name(fallback_id));
		{
			bool ssbo_block = type.storage == StorageClassStorageBuffer ||
			                  (type.storage == StorageClassUniform && typeflags.get(DecorationBufferBlock));
			if (ssbo_block)
			{
				auto buffer_flags = get_buffer_block_flags(res.id);
				if (buffer_flags.get(DecorationNonReadable))
					json_stream->emit_json_key_value("writeonly", true);
				if (buffer_flags.get(DecorationNonWritable))
					json_stream->emit_json_key_value("readonly", true);
				if (buffer_flags.get(DecorationRestrict))
					json_stream->emit_json_key_value("restrict", true);
				if (buffer_flags.get(DecorationCoherent))
					json_stream->emit_json_key_value("coherent", true);
			}
		}

		emit_type_array(type);

		{
			bool is_sized_block = is_block && (get_storage_class(res.id) == StorageClassUniform ||
			                                   get_storage_class(res.id) == StorageClassUniformConstant);
			if (is_sized_block)
			{
				uint32_t block_size = uint32_t(get_declared_struct_size(get_type(res.base_type_id)));
				json_stream->emit_json_key_value("block_size", block_size);
			}
		}

		if (type.storage == StorageClassPushConstant)
			json_stream->emit_json_key_value("push_constant", true);
		if (mask.get(DecorationLocation))
			json_stream->emit_json_key_value("location", get_decoration(res.id, DecorationLocation));
		if (mask.get(DecorationRowMajor))
			json_stream->emit_json_key_value("row_major", true);
		if (mask.get(DecorationColMajor))
			json_stream->emit_json_key_value("column_major", true);
		if (mask.get(DecorationIndex))
			json_stream->emit_json_key_value("index", get_decoration(res.id, DecorationIndex));
		if (type.storage != StorageClassPushConstant && mask.get(DecorationDescriptorSet))
			json_stream->emit_json_key_value("set", get_decoration(res.id, DecorationDescriptorSet));
		if (mask.get(DecorationBinding))
			json_stream->emit_json_key_value("binding", get_decoration(res.id, DecorationBinding));
		if (mask.get(DecorationInputAttachmentIndex))
			json_stream->emit_json_key_value("input_attachment_index",
			                                 get_decoration(res.id, DecorationInputAttachmentIndex));
		if (mask.get(DecorationOffset))
			json_stream->emit_json_key_value("offset", get_decoration(res.id, DecorationOffset));

		// For images, the type itself adds a layout qualifer.
		// Only emit the format for storage images.
		if (type.basetype == SPIRType::Image && type.image.sampled == 2)
		{
			const char *fmt = format_to_glsl(type.image.format);
			if (fmt != nullptr)
				json_stream->emit_json_key_value("format", std::string(fmt));
		}
		json_stream->end_json_object();
	}
	json_stream->end_json_array();
}

void CompilerReflection::emit_specialization_constants()
{
	auto specialization_constants = get_specialization_constants();
	if (specialization_constants.empty())
		return;

	json_stream->emit_json_key_array("specialization_constants");
	for (const auto spec_const : specialization_constants)
	{
		auto &c = get<SPIRConstant>(spec_const.id);
		auto type = get<SPIRType>(c.constant_type);
		json_stream->begin_json_object();
		json_stream->emit_json_key_value("id", spec_const.constant_id);
		json_stream->emit_json_key_value("type", type_to_glsl(type));
		switch (type.basetype)
		{
		case SPIRType::UInt:
			json_stream->emit_json_key_value("default_value", c.scalar());
			break;

		case SPIRType::Int:
			json_stream->emit_json_key_value("default_value", c.scalar_i32());
			break;

		case SPIRType::Float:
			json_stream->emit_json_key_value("default_value", c.scalar_f32());
			break;

		case SPIRType::Boolean:
			json_stream->emit_json_key_value("default_value", c.scalar() != 0);
			break;

		default:
			break;
		}
		json_stream->end_json_object();
	}
	json_stream->end_json_array();
}

string CompilerReflection::to_member_name(const SPIRType &type, uint32_t index) const
{
	auto &memb = ir.meta[type.self].members;
	if (index < memb.size() && !memb[index].alias.empty())
		return memb[index].alias;
	else
		return join("_m", index);
}
