/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 Google Inc.
 * Copyright (c) 2016 The Khronos Group 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 OpenGL ES Extensions Test Package.
 */ /*-------------------------------------------------------------------*/

#include "esextcTestPackage.hpp"

#include "draw_elements_base_vertex/esextcDrawElementsBaseVertexTests.hpp"
#include "geometry_shader/esextcGeometryShaderTests.hpp"
#include "gpu_shader5/esextcGPUShader5Tests.hpp"
#include "tessellation_shader/esextcTessellationShaderTests.hpp"
#include "texture_border_clamp/esextcTextureBorderClampTests.hpp"
#include "texture_buffer/esextcTextureBufferTests.hpp"
#include "texture_cube_map_array/esextcTextureCubeMapArrayTests.hpp"
#include "texture_shadow_lod/esextcTextureShadowLodFunctionsTest.hpp"

#include "glcViewportArrayTests.hpp"
#include "gluStateReset.hpp"
#include "tcuTestLog.hpp"
#include "tcuWaiverUtil.hpp"

namespace esextcts
{

class TestCaseWrapper : public tcu::TestCaseExecutor
{
public:
	TestCaseWrapper(ESEXTTestPackage& package, de::SharedPtr<tcu::WaiverUtil> waiverMechanism);
	~TestCaseWrapper(void);

	void init(tcu::TestCase* testCase, const std::string& path);
	void deinit(tcu::TestCase* testCase);
	tcu::TestNode::IterateResult iterate(tcu::TestCase* testCase);

private:
	ESEXTTestPackage& m_testPackage;
	de::SharedPtr<tcu::WaiverUtil> m_waiverMechanism;
};

TestCaseWrapper::TestCaseWrapper(ESEXTTestPackage& package, de::SharedPtr<tcu::WaiverUtil> waiverMechanism)
	: m_testPackage(package), m_waiverMechanism(waiverMechanism)
{
}

TestCaseWrapper::~TestCaseWrapper(void)
{
}

void TestCaseWrapper::init(tcu::TestCase* testCase, const std::string& path)
{
	if (m_waiverMechanism->isOnWaiverList(path))
		throw tcu::TestException("Waived test", QP_TEST_RESULT_WAIVER);

	glu::resetState(m_testPackage.getContext().getRenderContext(), m_testPackage.getContext().getContextInfo());

	testCase->init();
}

void TestCaseWrapper::deinit(tcu::TestCase* testCase)
{
	testCase->deinit();

	glu::resetState(m_testPackage.getContext().getRenderContext(), m_testPackage.getContext().getContextInfo());
}

tcu::TestNode::IterateResult TestCaseWrapper::iterate(tcu::TestCase* testCase)
{
	tcu::TestContext&			 testCtx   = m_testPackage.getContext().getTestContext();
	glu::RenderContext&			 renderCtx = m_testPackage.getContext().getRenderContext();
	tcu::TestCase::IterateResult result;

	result = testCase->iterate();

	// Call implementation specific post-iterate routine (usually handles native events and swaps buffers)
	try
	{
		renderCtx.postIterate();
		return result;
	}
	catch (const tcu::ResourceError&)
	{
		testCtx.getLog().endCase(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine");
		testCtx.setTerminateAfter(true);
		return tcu::TestNode::STOP;
	}
	catch (const std::exception&)
	{
		testCtx.getLog().endCase(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine");
		return tcu::TestNode::STOP;
	}
}

ESEXTTestPackage::ESEXTTestPackage(tcu::TestContext& testCtx, const char* packageName)
	: TestPackage(testCtx, packageName, "OpenGL ES Extensions Conformance Tests",
				  glu::ContextType(glu::ApiType::es(3, 1)), "gl_cts/data/")
{
}

ESEXTTestPackage::~ESEXTTestPackage(void)
{
}

void ESEXTTestPackage::init(void)
{
	// Call init() in parent - this creates context.
	TestPackage::init();

	try
	{
		const glu::ContextType& context_type = getContext().getRenderContext().getType();
		glcts::ExtParameters	extParams(glu::GLSL_VERSION_310_ES, glcts::EXTENSIONTYPE_EXT);
		if (glu::contextSupports(context_type, glu::ApiType::es(3, 2)))
		{
			extParams.glslVersion = glu::GLSL_VERSION_320_ES;
			extParams.extType	 = glcts::EXTENSIONTYPE_NONE;
		}

		addChild(new glcts::GeometryShaderTests(getContext(), extParams));
		addChild(new glcts::GPUShader5Tests(getContext(), extParams));
		addChild(new glcts::TessellationShaderTests(getContext(), extParams));
		addChild(new glcts::TextureCubeMapArrayTests(getContext(), extParams));
		addChild(new glcts::TextureBorderClampTests(getContext(), extParams));
		addChild(new glcts::TextureBufferTests(getContext(), extParams));
		addChild(new glcts::DrawElementsBaseVertexTests(getContext(), extParams));
		glcts::ExtParameters viewportParams(glu::GLSL_VERSION_310_ES, glcts::EXTENSIONTYPE_OES);
		addChild(new glcts::ViewportArrayTests(getContext(), viewportParams));
		addChild(new deqp::Functional::TextureShadowLodTest(getContext()));
	}
	catch (...)
	{
		// Destroy context.
		TestPackage::deinit();
		throw;
	}
}

tcu::TestCaseExecutor* ESEXTTestPackage::createExecutor(void) const
{
	return new TestCaseWrapper(const_cast<ESEXTTestPackage&>(*this), m_waiverMechanism);
}

} // esextcts
