#ifndef _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
#define _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Protected content buffer validator helper
 *//*--------------------------------------------------------------------*/

#include "tcuVector.hpp"
#include "vkDefs.hpp"
#include "vktTestCase.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"

#include "vkBuilderUtil.hpp"
#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestGroupUtil.hpp"
#include "tcuStringTemplate.hpp"

#include "vktProtectedMemUtils.hpp"
#include "vktProtectedMemContext.hpp"

namespace vkt
{
namespace ProtectedMem
{

class ProtectedContext;

template<typename T>
struct ValidationData {
	const tcu::IVec4	positions[4];
	const T				values[4];
};

template<typename T>
struct ValidationDataStorage {
	T					values;
};

typedef ValidationData<tcu::UVec4>	ValidationDataUVec4;
typedef ValidationData<tcu::IVec4>	ValidationDataIVec4;
typedef ValidationData<tcu::Vec4>	ValidationDataVec4;

enum TestType {
	TYPE_UINT,
	TYPE_INT,
	TYPE_FLOAT,
};

enum BufferType {
	SAMPLER_BUFFER,
	STORAGE_BUFFER,
};

void					initBufferValidatorPrograms		(vk::SourceCollections&	programCollection, TestType testType, BufferType bufferType);
vk::VkDescriptorType	getDescriptorType				(BufferType bufferType);

template<typename T>
class BufferValidator
{
public:
									BufferValidator			(const ValidationData<T> data)
										: m_refData			(data)
										, m_refDataStorage	(*reinterpret_cast<ValidationDataStorage<T>*>( &std::vector<char>(sizeof(ValidationDataStorage<T>), '\0').front()))
										, m_bufferType		(SAMPLER_BUFFER)
									{
									}

									BufferValidator			(const ValidationDataStorage<T> data)
										: m_refData			(*reinterpret_cast<ValidationData<T>*>( &std::vector<char>(sizeof(ValidationData<T>), '\0').front()))
										, m_refDataStorage	(data)
										, m_bufferType		(STORAGE_BUFFER)
									{
									}

									~BufferValidator		() {}
	void							initPrograms			(vk::SourceCollections&	programCollection) const;

	bool							validateBuffer			(ProtectedContext&	ctx,
																 const vk::VkBuffer	buffer) const;
private:
	deUint32						getReferenceDataSize	() const;
	const void *					getReferenceDataSrc		() const;
	void							printReferenceInfo		(ProtectedContext&		ctx) const;

	const ValidationData<T>			m_refData;
	const ValidationDataStorage<T>	m_refDataStorage;

	BufferType						m_bufferType;
};

template<>
inline void BufferValidator<tcu::UVec4>::initPrograms (vk::SourceCollections& programCollection) const
{
	initBufferValidatorPrograms(programCollection, TYPE_UINT, m_bufferType);
}

template<>
inline void BufferValidator<tcu::IVec4>::initPrograms (vk::SourceCollections& programCollection) const
{
	initBufferValidatorPrograms(programCollection, TYPE_INT, m_bufferType);
}

template<>
inline void BufferValidator<tcu::Vec4>::initPrograms (vk::SourceCollections& programCollection) const
{
	initBufferValidatorPrograms(programCollection, TYPE_FLOAT, m_bufferType);
}

template<typename T>
deUint32 BufferValidator<T>::getReferenceDataSize () const
{
	return m_bufferType == SAMPLER_BUFFER ? (deUint32)sizeof(m_refData) : (deUint32)sizeof(m_refDataStorage);
}

template<typename T>
const void * BufferValidator<T>::getReferenceDataSrc () const
{
	return m_bufferType == SAMPLER_BUFFER ? (void*)&m_refData : (void*)&m_refDataStorage;
}

template<typename T>
void BufferValidator<T>::printReferenceInfo (ProtectedContext& ctx) const
{
	if (m_bufferType == SAMPLER_BUFFER)
	{
		ctx.getTestContext().getLog()
				<< tcu::TestLog::Message << "Reference positions: \n"
				<< "1: " << m_refData.positions[0] << "\n"
				<< "2: " << m_refData.positions[1] << "\n"
				<< "3: " << m_refData.positions[2] << "\n"
				<< "4: " << m_refData.positions[3] << "\n"
				<< tcu::TestLog::EndMessage
				<< tcu::TestLog::Message << "Reference fill values: \n"
				<< "1: " << m_refData.values[0] << "\n"
				<< "2: " << m_refData.values[1] << "\n"
				<< "3: " << m_refData.values[2] << "\n"
				<< "4: " << m_refData.values[3] << "\n"
				<< tcu::TestLog::EndMessage;
	} else if (m_bufferType == STORAGE_BUFFER)
	{
		ctx.getTestContext().getLog()
				<< tcu::TestLog::Message << "Reference values: \n"
				<< "1: " << m_refDataStorage.values << "\n"
				<< tcu::TestLog::EndMessage;
	}
}

template<typename T>
bool BufferValidator<T>::validateBuffer (ProtectedContext&		ctx,
										 const vk::VkBuffer		buffer) const
{
	// Log out a few reference info
	printReferenceInfo(ctx);

	const deUint64							oneSec				= 1000 * 1000 * 1000;

	const vk::DeviceInterface&				vk					= ctx.getDeviceInterface();
	const vk::VkDevice						device				= ctx.getDevice();
	const vk::VkQueue						queue				= ctx.getQueue();
	const deUint32							queueFamilyIndex	= ctx.getQueueFamilyIndex();

	vk::Move<vk::VkBufferView>				bufferView;

	const deUint32							refDataSize			= getReferenceDataSize();
	de::UniquePtr<vk::BufferWithMemory>		refUniform			(makeBuffer(ctx,
																 PROTECTION_DISABLED,
																 queueFamilyIndex,
																 refDataSize,
																 vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
																 vk::MemoryRequirement::HostVisible));

	// Set the reference uniform data
	{
		deMemcpy(refUniform->getAllocation().getHostPtr(), getReferenceDataSrc(), refDataSize);
		vk::flushMappedMemoryRange(vk, device, refUniform->getAllocation().getMemory(), refUniform->getAllocation().getOffset(), refDataSize);
	}

	const deUint32							helperBufferSize	= (deUint32)(2 * sizeof(deUint32));
	de::MovePtr<vk::BufferWithMemory>		helperBuffer		(makeBuffer(ctx,
																 PROTECTION_ENABLED,
																 queueFamilyIndex,
																 helperBufferSize,
																 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
																 vk::MemoryRequirement::Any));
	vk::Unique<vk::VkShaderModule>			resetSSBOShader		(vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("ResetSSBO"), 0));
	vk::Unique<vk::VkShaderModule>			validatorShader		(vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("BufferValidator"), 0));

	// Create descriptors
	vk::Unique<vk::VkDescriptorSetLayout>	descriptorSetLayout	(vk::DescriptorSetLayoutBuilder()
																	.addSingleBinding(getDescriptorType(m_bufferType), vk::VK_SHADER_STAGE_COMPUTE_BIT)
																	.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
																	.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
																	.build(vk, device));
	vk::Unique<vk::VkDescriptorPool>		descriptorPool		(vk::DescriptorPoolBuilder()
																	.addType(getDescriptorType(m_bufferType), 1u)
																	.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
																	.addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)
																	.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	vk::Unique<vk::VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));


	// Update descriptor set information
	{
		vk::VkDescriptorBufferInfo	descRefUniform	= makeDescriptorBufferInfo(**refUniform, 0, refDataSize);
		vk::VkDescriptorBufferInfo	descBuffer		= makeDescriptorBufferInfo(**helperBuffer, 0, helperBufferSize);

		vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
		switch (m_bufferType)
		{
			case SAMPLER_BUFFER:
			{
				const vk::VkBufferViewCreateInfo		viewParams			=
					{
						vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType
						DE_NULL,										// const void*				pNext
						0u,												// VkBufferViewCreateFlags	flags
						buffer,											// VkBuffer					buffer
						vk::VK_FORMAT_R32G32B32A32_UINT,				// VkFormat					format
						0u,												// VkDeviceSize				offset
						VK_WHOLE_SIZE									// VkDeviceSize				range
					};
				bufferView = vk::Move<vk::VkBufferView> (vk::createBufferView(vk, device, &viewParams));
				descriptorSetUpdateBuilder
					.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, &bufferView.get());
				break;
			}
			case STORAGE_BUFFER:
			{
				const deUint32					testBufferSize	= (deUint32)(sizeof(ValidationDataStorage<T>));
				vk::VkDescriptorBufferInfo		descTestBuffer	= makeDescriptorBufferInfo(buffer, 0, testBufferSize);
				descriptorSetUpdateBuilder
					.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descTestBuffer);
				break;
			}
		}
		descriptorSetUpdateBuilder
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descBuffer)
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descRefUniform)
		.update(vk, device);
	}

	// Build pipeline
	vk::Unique<vk::VkPipelineLayout>		pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));

	vk::Unique<vk::VkCommandPool>			cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));

	// Reset helper SSBO
	{
		const vk::Unique<vk::VkFence>		fence				(vk::createFence(vk, device));
		vk::Unique<vk::VkPipeline>			resetSSBOPipeline	(makeComputePipeline(vk, device, *pipelineLayout, *resetSSBOShader, DE_NULL));
		vk::Unique<vk::VkCommandBuffer>		resetCmdBuffer		(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		beginCommandBuffer(vk, *resetCmdBuffer);

		vk.cmdBindPipeline(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *resetSSBOPipeline);
		vk.cmdBindDescriptorSets(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
		vk.cmdDispatch(*resetCmdBuffer, 1u, 1u, 1u);

		VK_CHECK(vk.endCommandBuffer(*resetCmdBuffer));
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *resetCmdBuffer, *fence, ~0ull));
	}

	// Create validation compute commands & submit
	vk::VkResult							queueSubmitResult;
	{
		const vk::Unique<vk::VkFence>		fence				(vk::createFence(vk, device));
		vk::Unique<vk::VkPipeline>			validationPipeline	(makeComputePipeline(vk, device, *pipelineLayout, *validatorShader, DE_NULL));
		vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

		beginCommandBuffer(vk, *cmdBuffer);

		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *validationPipeline);
		vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
		vk.cmdDispatch(*cmdBuffer, 1u, 1u, 1u);

		VK_CHECK(vk.endCommandBuffer(*cmdBuffer));

		queueSubmitResult = queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, oneSec);
	}

	// \todo do we need to check the fence status?
	if (queueSubmitResult == vk::VK_TIMEOUT)
		return false;

	// at this point the submit result should be VK_TRUE
	VK_CHECK(queueSubmitResult);
	return true;
}


} // ProtectedMem
} // vkt

#endif // _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
