#ifndef _VKTTESTCASEUTIL_HPP
#define _VKTTESTCASEUTIL_HPP
/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * 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 TestCase utilities
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "tcuResource.hpp"
#include "vktTestCase.hpp"

namespace vkt
{

class ShaderSourceProvider
{
public:
	static std::string getSource (tcu::Archive& archive, const char* path)
	{
		de::UniquePtr<tcu::Resource> resource(archive.getResource(path));

		std::vector<deUint8> readBuffer(resource->getSize() + 1);
		resource->read(&readBuffer[0], resource->getSize());
		readBuffer[readBuffer.size() - 1] = 0;

		return std::string(reinterpret_cast<const char*>(&readBuffer[0]));
	}
};

template<typename Arg0>
struct NoPrograms1
{
	void	init	(vk::SourceCollections&, Arg0) const {}
};

template<typename Instance, typename Arg0, typename Programs = NoPrograms1<Arg0> >
class InstanceFactory1 : public TestCase
{
public:
					InstanceFactory1	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Arg0& arg0)
						: TestCase	(testCtx, type, name, desc)
						, m_progs	()
						, m_arg0	(arg0)
					{}

					InstanceFactory1	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Programs& progs, const Arg0& arg0)
						: TestCase	(testCtx, type, name, desc)
						, m_progs	(progs)
						, m_arg0	(arg0)
					{}

	void			initPrograms	(vk::SourceCollections& dst)	const { m_progs.init(dst, m_arg0); }
	TestInstance*	createInstance	(Context& context)				const { return new Instance(context, m_arg0); }
	void			checkSupport	(Context&)						const { }

private:
	const Programs	m_progs;
	const Arg0		m_arg0;
};

template<typename Instance, typename Arg0, typename Support, typename Programs = NoPrograms1<Arg0> >
class InstanceFactory1WithSupport : public TestCase
{
public:

					InstanceFactory1WithSupport	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Arg0& arg0, const Support& support)
						: TestCase	(testCtx, type, name, desc)
						, m_progs	()
						, m_arg0	(arg0)
						, m_support	(support)
					{}

					InstanceFactory1WithSupport	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Programs& progs, const Arg0& arg0, const Support& support)
						: TestCase	(testCtx, type, name, desc)
						, m_progs	(progs)
						, m_arg0	(arg0)
						, m_support	(support)
					{}

	void			initPrograms	(vk::SourceCollections& dst)	const { m_progs.init(dst, m_arg0); }
	TestInstance*	createInstance	(Context& context)				const { return new Instance(context, m_arg0); }
	void			checkSupport	(Context& context)				const { m_support.checkSupport(context); }

private:
	const Programs	m_progs;
	const Arg0		m_arg0;
	const Support	m_support;
};

class FunctionInstance0 : public TestInstance
{
public:
	typedef tcu::TestStatus	(*Function)	(Context& context);

					FunctionInstance0	(Context& context, Function function)
						: TestInstance	(context)
						, m_function	(function)
					{}

	tcu::TestStatus	iterate				(void) { return m_function(m_context); }

private:
	const Function	m_function;
};

template<typename Arg0>
class FunctionInstance1 : public TestInstance
{
public:
	typedef tcu::TestStatus	(*Function)	(Context& context, Arg0 arg0);

	struct Args
	{
		Args (Function func_, Arg0 arg0_) : func(func_), arg0(arg0_) {}

		Function	func;
		Arg0		arg0;
	};

					FunctionInstance1	(Context& context, const Args& args)
						: TestInstance	(context)
						, m_args		(args)
					{}

	tcu::TestStatus	iterate				(void) { return m_args.func(m_context, m_args.arg0); }

private:
	const Args		m_args;
};

class FunctionPrograms0
{
public:
	typedef void	(*Function)		(vk::SourceCollections& dst);

					FunctionPrograms0	(Function func)
						: m_func(func)
					{}

	void			init			(vk::SourceCollections& dst, FunctionInstance0::Function) const { m_func(dst); }

private:
	const Function	m_func;
};

struct NoSupport0
{
	void			checkSupport	(Context&) const {};
};

class FunctionSupport0
{
public:
	typedef void	(*Function)	(Context& context);

					FunctionSupport0 (Function function)
						: m_function(function)
					{}

	void			checkSupport (Context& context) const { m_function(context); }

private:
	const Function	m_function;
};

template<typename Arg0>
struct NoSupport1
{
	void			checkSupport	(Context&, Arg0) const {};
};

template<typename Arg0>
class FunctionSupport1
{
public:
	typedef void	(*Function)	(Context& context, Arg0 arg0);

	struct Args
	{
		Args (Function func_, Arg0 arg0_)
			: func(func_)
			, arg0(arg0_)
		{}

		Function	func;
		Arg0		arg0;
	};

					FunctionSupport1 (const Args& args)
						: m_args(args)
					{}

	void			checkSupport (Context& context) const { return m_args.func(context, m_args.arg0); }

private:
	const Args		m_args;
};

template<typename Arg0>
class FunctionPrograms1
{
public:
	typedef void	(*Function)		(vk::SourceCollections& dst, Arg0 arg0);

					FunctionPrograms1	(Function func)
						: m_func(func)
					{}

	void			init			(vk::SourceCollections& dst, const typename FunctionInstance1<Arg0>::Args& args) const { m_func(dst, args.arg0); }

private:
	const Function	m_func;
};

// createFunctionCase

inline TestCase* createFunctionCase (tcu::TestContext&				testCtx,
									 tcu::TestNodeType				type,
									 const std::string&				name,
									 const std::string&				desc,
									 FunctionInstance0::Function	testFunction)
{
	return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function>(testCtx, type, name, desc, testFunction);
}

inline TestCase* createFunctionCase (tcu::TestContext&				testCtx,
									 tcu::TestNodeType				type,
									 const std::string&				name,
									 const std::string&				desc,
									 FunctionSupport0::Function		checkSupport,
									 FunctionInstance0::Function	testFunction)
{
	return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0>(testCtx, type, name, desc, testFunction, checkSupport);
}

inline TestCase* createFunctionCaseWithPrograms (tcu::TestContext&				testCtx,
												 tcu::TestNodeType				type,
												 const std::string&				name,
												 const std::string&				desc,
												 FunctionPrograms0::Function	initPrograms,
												 FunctionInstance0::Function	testFunction)
{
	return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function, FunctionPrograms0>(
		testCtx, type, name, desc, FunctionPrograms0(initPrograms), testFunction);
}

inline TestCase* createFunctionCaseWithPrograms (tcu::TestContext&				testCtx,
												 tcu::TestNodeType				type,
												 const std::string&				name,
												 const std::string&				desc,
												 FunctionSupport0::Function		checkSupport,
												 FunctionPrograms0::Function	initPrograms,
												 FunctionInstance0::Function	testFunction)
{
	return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0, FunctionPrograms0>(
		testCtx, type, name, desc, FunctionPrograms0(initPrograms), testFunction, checkSupport);
}

template<typename Arg0>
TestCase* createFunctionCase (tcu::TestContext&								testCtx,
							  tcu::TestNodeType								type,
							  const std::string&							name,
							  const std::string&							desc,
							  typename FunctionInstance1<Arg0>::Function	testFunction,
							  Arg0											arg0)
{
	return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args>(
		testCtx, type, name, desc, typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
}

template<typename Arg0>
TestCase* createFunctionCase (tcu::TestContext&								testCtx,
							  tcu::TestNodeType								type,
							  const std::string&							name,
							  const std::string&							desc,
							  typename FunctionSupport1<Arg0>::Function		checkSupport,
							  typename FunctionInstance1<Arg0>::Function	testFunction,
							  Arg0											arg0)
{
	return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionSupport1<Arg0> >(
		testCtx, type, name, desc, typename FunctionInstance1<Arg0>::Args(testFunction, arg0), typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
}

template<typename Arg0>
TestCase* createFunctionCaseWithPrograms (tcu::TestContext&								testCtx,
										  tcu::TestNodeType								type,
										  const std::string&							name,
										  const std::string&							desc,
										  typename FunctionPrograms1<Arg0>::Function	initPrograms,
										  typename FunctionInstance1<Arg0>::Function	testFunction,
										  Arg0											arg0)
{
	return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionPrograms1<Arg0> >(
		testCtx, type, name, desc, FunctionPrograms1<Arg0>(initPrograms), typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
}

template<typename Arg0>
TestCase* createFunctionCaseWithPrograms (tcu::TestContext&								testCtx,
										  tcu::TestNodeType								type,
										  const std::string&							name,
										  const std::string&							desc,
										  typename FunctionSupport1<Arg0>::Function		checkSupport,
										  typename FunctionPrograms1<Arg0>::Function	initPrograms,
										  typename FunctionInstance1<Arg0>::Function	testFunction,
										  Arg0											arg0)
{
	return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionSupport1<Arg0>, FunctionPrograms1<Arg0> >(
		testCtx, type, name, desc, FunctionPrograms1<Arg0>(initPrograms), typename FunctionInstance1<Arg0>::Args(testFunction, arg0), typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
}

// addFunctionCase

inline void addFunctionCase (tcu::TestCaseGroup*			group,
							 const std::string&				name,
							 const std::string&				desc,
							 FunctionInstance0::Function	testFunc)
{
	group->addChild(createFunctionCase(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, testFunc));
}

inline void addFunctionCase (tcu::TestCaseGroup*			group,
							 const std::string&				name,
							 const std::string&				desc,
							 FunctionSupport0::Function		checkSupport,
							 FunctionInstance0::Function	testFunc)
{
	group->addChild(createFunctionCase(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, testFunc));
}

inline void addFunctionCaseWithPrograms (tcu::TestCaseGroup*			group,
										 const std::string&				name,
										 const std::string&				desc,
										 FunctionPrograms0::Function	initPrograms,
										 FunctionInstance0::Function	testFunc)
{
	group->addChild(createFunctionCaseWithPrograms(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, initPrograms, testFunc));
}

inline void addFunctionCaseWithPrograms (tcu::TestCaseGroup*			group,
										 const std::string&				name,
										 const std::string&				desc,
										 FunctionSupport0::Function		checkSupport,
										 FunctionPrograms0::Function	initPrograms,
										 FunctionInstance0::Function	testFunc)
{
	group->addChild(createFunctionCaseWithPrograms(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, initPrograms, testFunc));
}

template<typename Arg0>
void addFunctionCase (tcu::TestCaseGroup*							group,
					  const std::string&							name,
					  const std::string&							desc,
					  typename FunctionInstance1<Arg0>::Function	testFunc,
					  Arg0											arg0)
{
	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, testFunc, arg0));
}

template<typename Arg0>
void addFunctionCase (tcu::TestCaseGroup*							group,
					  const std::string&							name,
					  const std::string&							desc,
					  typename FunctionSupport1<Arg0>::Function		checkSupport,
					  typename FunctionInstance1<Arg0>::Function	testFunc,
					  Arg0											arg0)
{
	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, testFunc, arg0));
}

template<typename Arg0>
void addFunctionCase (tcu::TestCaseGroup*							group,
					  tcu::TestNodeType								type,
					  const std::string&							name,
					  const std::string&							desc,
					  typename FunctionInstance1<Arg0>::Function	testFunc,
					  Arg0											arg0)
{
	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), type, name, desc, testFunc, arg0));
}

template<typename Arg0>
void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
								  const std::string&							name,
								  const std::string&							desc,
								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
								  typename FunctionInstance1<Arg0>::Function	testFunc,
								  Arg0											arg0)
{
	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, initPrograms, testFunc, arg0));
}

template<typename Arg0>
void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
								  const std::string&							name,
								  const std::string&							desc,
								  typename FunctionSupport1<Arg0>::Function		checkSupport,
								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
								  typename FunctionInstance1<Arg0>::Function	testFunc,
								  Arg0											arg0)
{
	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, initPrograms, testFunc, arg0));
}

template<typename Arg0>
void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
								  tcu::TestNodeType								type,
								  const std::string&							name,
								  const std::string&							desc,
								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
								  typename FunctionInstance1<Arg0>::Function	testFunc,
								  Arg0											arg0)
{
	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), type, name, desc, initPrograms, testFunc, arg0));
}

} // vkt

#endif // _VKTTESTCASEUTIL_HPP
