#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 "vkCmdUtil.hpp"
#include "vkObjUtil.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::Protected));
	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);

		endCommandBuffer(vk, *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);

		endCommandBuffer(vk, *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
