/*-------------------------------------------------------------------------
 * 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 3 Test Package.
 */ /*-------------------------------------------------------------------*/

#include "es32cTestPackage.hpp"
#include "es32cCopyImageTests.hpp"
#include "esextcTestPackage.hpp"
#include "glcAggressiveShaderOptimizationsTests.hpp"
#include "glcFragDepthTests.hpp"
#include "glcInfoTests.hpp"
#include "glcInternalformatTests.hpp"
#include "glcSeparableProgramsTransformFeedbackTests.hpp"
#include "glcShaderConstExprTests.hpp"
#include "glcShaderIndexingTests.hpp"
#include "glcShaderIntegerMixTests.hpp"
#include "glcShaderLibrary.hpp"
#include "glcShaderLoopTests.hpp"
#include "glcShaderMacroTests.hpp"
#include "glcShaderNegativeTests.hpp"
#include "glcShaderStructTests.hpp"
#include "glcTextureCompatibilityTests.hpp"
#include "glcUniformBlockTests.hpp"
#include "glcNearestEdgeTests.hpp"
#include "glcFramebufferCompleteness.hpp"
#include "glcCompressedFormatTests.hpp"
#include "gluStateReset.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include "tcuWaiverUtil.hpp"

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

namespace es32cts
{

class TestCaseWrapper : public tcu::TestCaseExecutor
{
public:
	TestCaseWrapper(ES32TestPackage& 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:
	ES32TestPackage&				m_testPackage;
	de::SharedPtr<tcu::WaiverUtil>	m_waiverMechanism;
};

TestCaseWrapper::TestCaseWrapper(ES32TestPackage& 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);

	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;

	// Clear to surrender-blue
	{
		const glw::Functions& gl = renderCtx.getFunctions();
		gl.clearColor(0.0f, 0.0f, 0.0f, 1.f);
		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	}

	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;
	}
}

ES32TestPackage::ES32TestPackage(tcu::TestContext& testCtx, const char* packageName)
	: deqp::TestPackage(testCtx, packageName, "OpenGL ES 3.2 Conformance Tests",
						glu::ContextType(glu::ApiType::es(3, 2)), "gl_cts/data/gles32/")
{
}

ES32TestPackage::~ES32TestPackage(void)
{
	deqp::TestPackage::deinit();
}

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

	try
	{
		// Add main test groups
		addChild(new deqp::InfoTests(getContext()));

		tcu::TestCaseGroup* shadersGroup = new tcu::TestCaseGroup(getTestContext(), "shaders", "");
		shadersGroup->addChild(new deqp::ShaderIntegerMixTests(getContext(), glu::GLSL_VERSION_320_ES));
		shadersGroup->addChild(new deqp::ShaderNegativeTests(getContext(), glu::GLSL_VERSION_320_ES));
		shadersGroup->addChild(new glcts::AggressiveShaderOptimizationsTests(getContext()));
		addChild(shadersGroup);

		tcu::TestCaseGroup*  coreGroup = new tcu::TestCaseGroup(getTestContext(), "core", "");
		glcts::ExtParameters extParams(glu::GLSL_VERSION_320_ES, glcts::EXTENSIONTYPE_NONE);
		coreGroup->addChild(new glcts::GeometryShaderTests(getContext(), extParams));
		coreGroup->addChild(new glcts::GPUShader5Tests(getContext(), extParams));
		coreGroup->addChild(new glcts::TessellationShaderTests(getContext(), extParams));
		coreGroup->addChild(new glcts::TextureCubeMapArrayTests(getContext(), extParams));
		coreGroup->addChild(new glcts::TextureBorderClampTests(getContext(), extParams));
		coreGroup->addChild(new glcts::TextureBufferTests(getContext(), extParams));
		coreGroup->addChild(new glcts::DrawBuffersIndexedTests(getContext(), extParams));
		coreGroup->addChild(new glcts::ShaderConstExprTests(getContext()));
		coreGroup->addChild(new glcts::ShaderMacroTests(getContext()));
		coreGroup->addChild(new glcts::SeparableProgramsTransformFeedbackTests(getContext()));
		coreGroup->addChild(new glcts::CopyImageTests(getContext()));
		coreGroup->addChild(new glcts::InternalformatTests(getContext()));
		coreGroup->addChild(new deqp::Functional::TextureShadowLodTest(getContext()));
		coreGroup->addChild(new glcts::NearestEdgeCases(getContext()));
		coreGroup->addChild(new glcts::FramebufferCompletenessTests(getContext()));
		coreGroup->addChild(new glcts::TextureCompatibilityTests(getContext()));
		coreGroup->addChild(new glcts::CompressedFormatTests(getContext()));
		addChild(coreGroup);
	}
	catch (...)
	{
		// Destroy context.
		deqp::TestPackage::deinit();
		throw;
	}
}

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

} // es32cts
