/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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 Common object lifetime tests.
 *//*--------------------------------------------------------------------*/

#include "glsLifetimeTests.hpp"

#include "deString.h"
#include "deRandom.hpp"
#include "deSTLUtil.hpp"
#include "deStringUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTestLog.hpp"
#include "gluDrawUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluDefs.hpp"
#include "glwFunctions.hpp"

#include <vector>
#include <map>
#include <algorithm>
#include <sstream>

namespace deqp
{
namespace gls
{
namespace LifetimeTests
{
namespace details
{

using std::map;
using std::string;
using std::ostringstream;
using de::Random;
using tcu::RenderTarget;
using tcu::RGBA;
using tcu::StringTemplate;
using tcu::TestCase;
typedef TestCase::IterateResult IterateResult;
using tcu::TestLog;
using tcu::ScopedLogSection;
using glu::Program;
using glu::Shader;
using glu::Framebuffer;
using glu::SHADERTYPE_VERTEX;
using glu::SHADERTYPE_FRAGMENT;
using namespace glw;

enum { VIEWPORT_SIZE = 128, FRAMEBUFFER_SIZE = 128 };

GLint getInteger (ContextWrapper& gl, GLenum queryParam)
{
	GLint ret = 0;
	GLU_CHECK_CALL_ERROR(
		gl.glGetIntegerv(queryParam, &ret),
		gl.glGetError());
	gl.log() << TestLog::Message << "// Single integer output: " << ret << TestLog::EndMessage;
	return ret;
}

#define GLSL100_SRC(BODY) ("#version 100\n" #BODY "\n")

static const char* const s_vertexShaderSrc = GLSL100_SRC(
	attribute vec2 pos;
	void main()
	{
		gl_Position = vec4(pos.xy, 0.0, 1.0);
	}
	);

static const char* const s_fragmentShaderSrc = GLSL100_SRC(
	void main()
	{
		gl_FragColor = vec4(1.0);
	}
	);

class CheckedShader : public Shader
{
public:
	CheckedShader (const RenderContext& renderCtx, glu::ShaderType type, const string& src)
		: Shader (renderCtx, type)
	{
		const char* const srcStr = src.c_str();
		setSources(1, &srcStr, DE_NULL);
		compile();
		TCU_CHECK(getCompileStatus());
	}
};

class CheckedProgram : public Program
{
public:
	CheckedProgram	(const RenderContext& renderCtx, GLuint vtxShader, GLuint fragShader)
		: Program	(renderCtx)
	{
		attachShader(vtxShader);
		attachShader(fragShader);
		link();
		TCU_CHECK(getLinkStatus());
	}
};

ContextWrapper::ContextWrapper (const Context& ctx)
	: CallLogWrapper	(ctx.gl(), ctx.log())
	, m_ctx				(ctx)
{
	enableLogging(true);
}

void SimpleBinder::bind (GLuint name)
{
	(this->*m_bindFunc)(m_bindTarget, name);
}

GLuint SimpleBinder::getBinding (void)
{
	return getInteger(*this, m_bindingParam);
}

GLuint SimpleType::gen (void)
{
	GLuint ret;
	(this->*m_genFunc)(1, &ret);
	return ret;
}

class VertexArrayBinder : public SimpleBinder
{
public:
						VertexArrayBinder	(Context& ctx)
							: SimpleBinder	(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true) {}
	void				bind				(GLuint name) { glBindVertexArray(name); }
};

class QueryBinder : public Binder
{
public:
						QueryBinder		(Context& ctx) : Binder(ctx) {}
	void				bind			(GLuint name)
	{
		if (name != 0)
			glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
		else
			glEndQuery(GL_ANY_SAMPLES_PASSED);
	}
	GLuint				getBinding		(void) { return 0; }
};

bool ProgramType::isDeleteFlagged (GLuint name)
{
	GLint deleteFlagged = 0;
	glGetProgramiv(name, GL_DELETE_STATUS, &deleteFlagged);
	return deleteFlagged != 0;
}

bool ShaderType::isDeleteFlagged (GLuint name)
{
	GLint deleteFlagged = 0;
	glGetShaderiv(name, GL_DELETE_STATUS, &deleteFlagged);
	return deleteFlagged != 0;
}

void setupFbo (const Context& ctx, GLuint seed, GLuint fbo)
{
	const Functions& gl = ctx.getRenderContext().getFunctions();

	GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
						 gl.getError());

	if (seed == 0)
	{
		gl.clearColor(0.0, 0.0, 0.0, 1.0);
		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
	}
	else
	{
		Random			rnd		(seed);
		const GLsizei	width	= rnd.getInt(0, FRAMEBUFFER_SIZE);
		const GLsizei	height	= rnd.getInt(0, FRAMEBUFFER_SIZE);
		const GLint		x		= rnd.getInt(0, FRAMEBUFFER_SIZE - width);
		const GLint		y		= rnd.getInt(0, FRAMEBUFFER_SIZE - height);
		const GLfloat	r1		= rnd.getFloat();
		const GLfloat	g1		= rnd.getFloat();
		const GLfloat	b1		= rnd.getFloat();
		const GLfloat	a1		= rnd.getFloat();
		const GLfloat	r2		= rnd.getFloat();
		const GLfloat	g2		= rnd.getFloat();
		const GLfloat	b2		= rnd.getFloat();
		const GLfloat	a2		= rnd.getFloat();

		GLU_CHECK_CALL_ERROR(gl.clearColor(r1, g1, b1, a1), gl.getError());
		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
		gl.scissor(x, y, width, height);
		gl.enable(GL_SCISSOR_TEST);
		gl.clearColor(r2, g2, b2, a2);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.disable(GL_SCISSOR_TEST);
	}

	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	GLU_CHECK_ERROR(gl.getError());
}

void drawFbo (const Context& ctx, GLuint fbo, Surface& dst)
{
	const RenderContext& renderCtx = ctx.getRenderContext();
	const Functions& gl = renderCtx.getFunctions();

	GLU_CHECK_CALL_ERROR(
		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
		gl.getError());

	dst.setSize(FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
	glu::readPixels(renderCtx, 0, 0, dst.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels from framebuffer");

	GLU_CHECK_CALL_ERROR(
		gl.bindFramebuffer(GL_FRAMEBUFFER, 0),
		gl.getError());
}

GLuint getFboAttachment (const Functions& gl, GLuint fbo, GLenum requiredType)
{
	GLint type = 0, name = 0;
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
	GLU_CHECK_CALL_ERROR(
		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
											   &type),
		gl.getError());

	if (GLenum(type) != requiredType || GLenum(type) == GL_NONE)
		return 0;

	GLU_CHECK_CALL_ERROR(
		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
											   &name),
		gl.getError());
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	GLU_CHECK_ERROR(gl.getError());

	return name;
}

void FboAttacher::initAttachment (GLuint seed, GLuint element)
{
	Binder& binder = *getElementType().binder();
	Framebuffer fbo(getRenderContext());

	enableLogging(false);

	binder.enableLogging(false);
	binder.bind(element);
	initStorage();
	binder.bind(0);
	binder.enableLogging(true);

	attach(element, *fbo);
	setupFbo(getContext(), seed, *fbo);
	detach(element, *fbo);

	enableLogging(true);

	log() << TestLog::Message
		  << "// Drew to " << getElementType().getName() << " " << element
		  << " with seed " << seed << "."
		  << TestLog::EndMessage;
}

void FboInputAttacher::drawContainer (GLuint fbo, Surface& dst)
{
	drawFbo(getContext(), fbo, dst);
	log() << TestLog::Message
		  << "// Read pixels from framebuffer " << fbo << " to output image."
		  << TestLog::EndMessage;
}

void FboOutputAttacher::setupContainer (GLuint seed, GLuint fbo)
{
	setupFbo(getContext(), seed, fbo);
	log() << TestLog::Message
		  << "// Drew to framebuffer " << fbo << " with seed " << seed << "."
		  << TestLog::EndMessage;
}

void FboOutputAttacher::drawAttachment (GLuint element, Surface& dst)
{
	Framebuffer fbo(getRenderContext());
	m_attacher.enableLogging(false);
	m_attacher.attach(element, *fbo);
	drawFbo(getContext(), *fbo, dst);
	m_attacher.detach(element, *fbo);
	m_attacher.enableLogging(true);
	log() << TestLog::Message
		  << "// Read pixels from " << m_attacher.getElementType().getName() << " " << element
		  << " to output image."
		  << TestLog::EndMessage;
	GLU_CHECK_ERROR(gl().getError());
}

void TextureFboAttacher::attach (GLuint texture, GLuint fbo)
{
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
								  GL_TEXTURE_2D, texture, 0),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, 0),
		gl().getError());
}

void TextureFboAttacher::detach (GLuint texture, GLuint fbo)
{
	DE_UNREF(texture);
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, 0),
		gl().getError());
}

GLuint TextureFboAttacher::getAttachment (GLuint fbo)
{
	return getFboAttachment(gl(), fbo, GL_TEXTURE);
}

void TextureFboAttacher::initStorage (void)
{
	GLU_CHECK_CALL_ERROR(
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
					 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, DE_NULL),
		gl().getError());
}

void RboFboAttacher::initStorage (void)
{
	GLU_CHECK_CALL_ERROR(
		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
		gl().getError());
}

void RboFboAttacher::attach (GLuint rbo, GLuint fbo)
{
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, 0),
		gl().getError());
}

void RboFboAttacher::detach (GLuint rbo, GLuint fbo)
{
	DE_UNREF(rbo);
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0),
		gl().getError());
	GLU_CHECK_CALL_ERROR(
		glBindFramebuffer(GL_FRAMEBUFFER, 0),
		gl().getError());
}

GLuint RboFboAttacher::getAttachment (GLuint fbo)
{
	return getFboAttachment(gl(), fbo, GL_RENDERBUFFER);
}

static const char* const s_fragmentShaderTemplate = GLSL100_SRC(
	void main()
	{
		gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0);
	}
	);

void ShaderProgramAttacher::initAttachment (GLuint seed, GLuint shader)
{
	using					de::insert;
	using					de::floatToString;

	Random					rnd(seed);
	map<string, string>		params;
	const StringTemplate	sourceTmpl	(s_fragmentShaderTemplate);

	insert(params, "RED",	floatToString(rnd.getFloat(), 4));
	insert(params, "GREEN",	floatToString(rnd.getFloat(), 4));
	insert(params, "BLUE",	floatToString(rnd.getFloat(), 4));

	{
		const string			source		= sourceTmpl.specialize(params);
		const char* const		sourceStr	= source.c_str();

		GLU_CHECK_CALL_ERROR(glShaderSource(shader, 1, &sourceStr, DE_NULL), gl().getError());
		GLU_CHECK_CALL_ERROR(glCompileShader(shader), gl().getError());

		{
			GLint compileStatus = 0;
			gl().getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
			TCU_CHECK_MSG(compileStatus != 0, sourceStr);
		}
	}
}

void ShaderProgramAttacher::attach (GLuint shader, GLuint program)
{
	GLU_CHECK_CALL_ERROR(
		glAttachShader(program, shader),
		gl().getError());
}

void ShaderProgramAttacher::detach (GLuint shader, GLuint program)
{
	GLU_CHECK_CALL_ERROR(
		glDetachShader(program, shader),
		gl().getError());
}

GLuint ShaderProgramAttacher::getAttachment (GLuint program)
{
	GLuint			shaders[2]	= { 0, 0 };
	const GLsizei	shadersLen	= DE_LENGTH_OF_ARRAY(shaders);
	GLsizei			numShaders	= 0;
	GLuint			ret			= 0;

	gl().getAttachedShaders(program, shadersLen, &numShaders, shaders);

	// There should ever be at most one attached shader in normal use, but if
	// something is wrong, the temporary vertex shader might not have been
	// detached properly, so let's find the fragment shader explicitly.
	for (int ndx = 0; ndx < de::min<GLsizei>(shadersLen, numShaders); ++ndx)
	{
		GLint shaderType = GL_NONE;
		gl().getShaderiv(shaders[ndx], GL_SHADER_TYPE, &shaderType);

		if (shaderType == GL_FRAGMENT_SHADER)
		{
			ret = shaders[ndx];
			break;
		}
	}

	return ret;
}

void setViewport (const RenderContext& renderCtx, const Rectangle& rect)
{
	renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
}

void readRectangle (const RenderContext& renderCtx, const Rectangle& rect, Surface& dst)
{
	dst.setSize(rect.width, rect.height);
	glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
}

Rectangle randomViewport (const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
						  Random& rnd)
{
	const RenderTarget&	target	= ctx.getRenderTarget();
	const GLint			width	= de::min(target.getWidth(), maxWidth);
	const GLint			xOff	= rnd.getInt(0, target.getWidth() - width);
	const GLint			height	= de::min(target.getHeight(), maxHeight);
	const GLint			yOff	= rnd.getInt(0, target.getHeight() - height);

	return Rectangle(xOff, yOff, width, height);
}

void ShaderProgramInputAttacher::drawContainer (GLuint program, Surface& dst)
{
	static const float	s_vertices[6]	= { -1.0, 0.0, 1.0, 1.0, 0.0, -1.0 };
	Random				rnd				(program);
	CheckedShader		vtxShader		(getRenderContext(),
										 SHADERTYPE_VERTEX, s_vertexShaderSrc);
	const Rectangle		viewport		= randomViewport(getRenderContext(),
														 VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);

	gl().attachShader(program, vtxShader.getShader());
	gl().linkProgram(program);

	{
		GLint linkStatus = 0;
		gl().getProgramiv(program, GL_LINK_STATUS, &linkStatus);
		TCU_CHECK(linkStatus != 0);
	}

	log() << TestLog::Message
		  << "// Attached a temporary vertex shader and linked program " << program
		  << TestLog::EndMessage;

	setViewport(getRenderContext(), viewport);
	log() << TestLog::Message << "// Positioned viewport randomly" << TestLog::EndMessage;

	glUseProgram(program);
	{
		GLint posLoc = gl().getAttribLocation(program, "pos");
		TCU_CHECK(posLoc >= 0);

		gl().enableVertexAttribArray(posLoc);

		gl().clearColor(0, 0, 0, 1);
		gl().clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl().vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, s_vertices);
		gl().drawArrays(GL_TRIANGLES, 0, 3);

		gl().disableVertexAttribArray(posLoc);
		log () << TestLog::Message << "// Drew a fixed triangle" << TestLog::EndMessage;
	}
	glUseProgram(0);

	readRectangle(getRenderContext(), viewport, dst);
	log() << TestLog::Message << "// Copied viewport to output image" << TestLog::EndMessage;

	gl().detachShader(program, vtxShader.getShader());
	log() << TestLog::Message << "// Removed temporary vertex shader" << TestLog::EndMessage;
}

ES2Types::ES2Types (const Context& ctx)
	: Types			(ctx)
	, m_bufferBind	(ctx, &CallLogWrapper::glBindBuffer,
					 GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING)
	, m_bufferType	(ctx, "buffer", &CallLogWrapper::glGenBuffers,
					 &CallLogWrapper::glDeleteBuffers,
					 &CallLogWrapper::glIsBuffer, &m_bufferBind)
	, m_textureBind	(ctx, &CallLogWrapper::glBindTexture, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D)
	, m_textureType	(ctx, "texture", &CallLogWrapper::glGenTextures,
					 &CallLogWrapper::glDeleteTextures,
					 &CallLogWrapper::glIsTexture, &m_textureBind)
	, m_rboBind		(ctx, &CallLogWrapper::glBindRenderbuffer,
					 GL_RENDERBUFFER, GL_RENDERBUFFER_BINDING)
	, m_rboType		(ctx, "renderbuffer",
					 &CallLogWrapper::glGenRenderbuffers,
					 &CallLogWrapper::glDeleteRenderbuffers,
					 &CallLogWrapper::glIsRenderbuffer, &m_rboBind)
	, m_fboBind		(ctx, &CallLogWrapper::glBindFramebuffer,
					 GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING)
	, m_fboType		(ctx, "framebuffer",
					 &CallLogWrapper::glGenFramebuffers,
					 &CallLogWrapper::glDeleteFramebuffers,
					 &CallLogWrapper::glIsFramebuffer, &m_fboBind)
	, m_shaderType	(ctx)
	, m_programType	(ctx)
	, m_texFboAtt	(ctx, m_textureType, m_fboType)
	, m_texFboInAtt	(m_texFboAtt)
	, m_texFboOutAtt(m_texFboAtt)
	, m_rboFboAtt	(ctx, m_rboType, m_fboType)
	, m_rboFboInAtt	(m_rboFboAtt)
	, m_rboFboOutAtt(m_rboFboAtt)
	, m_shaderAtt	(ctx, m_shaderType, m_programType)
	, m_shaderInAtt	(m_shaderAtt)
{
	Type* const types[] =
	{
		&m_bufferType, &m_textureType, &m_rboType, &m_fboType, &m_shaderType, &m_programType
	};
	m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));

	m_attachers.push_back(&m_texFboAtt);
	m_attachers.push_back(&m_rboFboAtt);
	m_attachers.push_back(&m_shaderAtt);

	m_inAttachers.push_back(&m_texFboInAtt);
	m_inAttachers.push_back(&m_rboFboInAtt);
	m_inAttachers.push_back(&m_shaderInAtt);

	m_outAttachers.push_back(&m_texFboOutAtt);
	m_outAttachers.push_back(&m_rboFboOutAtt);
}

class Name
{
public:
				Name		(Type& type) : m_type(type), m_name(type.gen()) {}
				Name		(Type& type, GLuint name) : m_type(type), m_name(name) {}
				~Name		(void) { m_type.release(m_name); }
	GLuint		operator*	(void) const { return m_name; }

private:
	Type&			m_type;
	const GLuint	m_name;
};

class ResultCollector
{
public:
					ResultCollector		(TestContext& testCtx);
	bool			check				(bool cond, const char* msg);
	void			fail				(const char* msg);
	void			warn				(const char* msg);
					~ResultCollector	(void);

private:
	void			addResult			(qpTestResult result, const char* msg);

	TestContext&	m_testCtx;
	TestLog&		m_log;
	qpTestResult	m_result;
	const char*		m_message;
};

ResultCollector::ResultCollector (TestContext& testCtx)
	: m_testCtx		(testCtx)
	, m_log			(testCtx.getLog())
	, m_result		(QP_TEST_RESULT_PASS)
	, m_message		("Pass")
{
}

bool ResultCollector::check (bool cond, const char* msg)
{
	if (!cond)
		fail(msg);
	return cond;
}

void ResultCollector::addResult (qpTestResult result, const char* msg)
{
	m_log << TestLog::Message << "// Fail: " << msg << TestLog::EndMessage;
	if (m_result == QP_TEST_RESULT_PASS)
	{
		m_result = result;
		m_message = msg;
	}
	else
	{
		if (result == QP_TEST_RESULT_FAIL)
			m_result = result;
		m_message = "Multiple problems, see log for details";
	}
}

void ResultCollector::fail (const char* msg)
{
	addResult(QP_TEST_RESULT_FAIL, msg);
}

void ResultCollector::warn (const char* msg)
{
	addResult(QP_TEST_RESULT_QUALITY_WARNING, msg);
}

ResultCollector::~ResultCollector (void)
{
	m_testCtx.setTestResult(m_result, m_message);
}

class TestBase : public TestCase, protected CallLogWrapper
{
protected:
							TestBase			(const char*	name,
												 const char*	description,
												 const Context&	ctx);

	// Copy ContextWrapper since MI (except for CallLogWrapper) is a no-no.
	const Context&			getContext			(void) const { return m_ctx; }
	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
	const Functions&		gl					(void) const { return m_ctx.gl(); }
	TestLog&				log					(void) const { return m_ctx.log(); }
	void					init				(void);

	Context					m_ctx;
	Random					m_rnd;
};

TestBase::TestBase (const char* name, const char* description, const Context& ctx)
	: TestCase			(ctx.getTestContext(), name, description)
	, CallLogWrapper	(ctx.gl(), ctx.log())
	, m_ctx				(ctx)
	, m_rnd				(deStringHash(name))
{
	enableLogging(true);
}

void TestBase::init (void)
{
	m_rnd = Random(deStringHash(getName()));
}

class LifeTest : public TestBase
{
public:
	typedef void			(LifeTest::*TestFunction)	(void);

							LifeTest					(const char*	name,
														 const char*	description,
														 Type&			type,
														 TestFunction	test)
								: TestBase		(name, description, type.getContext())
								, m_type		(type)
								, m_test		(test) {}

	IterateResult			iterate						(void);

	void					testGen						(void);
	void					testDelete					(void);
	void					testBind					(void);
	void					testDeleteBound				(void);
	void					testBindNoGen				(void);
	void					testDeleteUsed				(void);

private:
	Binder&					binder						(void) { return *m_type.binder(); }

	Type&					m_type;
	TestFunction			m_test;
};

IterateResult LifeTest::iterate (void)
{
	(this->*m_test)();
	return STOP;
}

void LifeTest::testGen (void)
{
	ResultCollector	errors	(getTestContext());
	Name			name	(m_type);

	if (m_type.genCreates())
		errors.check(m_type.exists(*name), "Gen* should have created an object, but didn't");
	else
		errors.check(!m_type.exists(*name), "Gen* should not have created an object, but did");
}

void LifeTest::testDelete (void)
{
	ResultCollector	errors	(getTestContext());
	GLuint			name	= m_type.gen();

	m_type.release(name);
	errors.check(!m_type.exists(name), "Object still exists after deletion");
}

void LifeTest::testBind (void)
{
	ResultCollector	errors	(getTestContext());
	Name			name	(m_type);

	binder().bind(*name);
	GLU_EXPECT_NO_ERROR(gl().getError(), "Bind failed");
	errors.check(m_type.exists(*name), "Object does not exist after binding");
	binder().bind(0);
}

void LifeTest::testDeleteBound (void)
{
	const GLuint	id		= m_type.gen();
	ResultCollector	errors	(getTestContext());

	binder().bind(id);
	m_type.release(id);

	if (m_type.nameLingers())
	{
		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
		errors.check(binder().getBinding() == id,
					 "Deleting bound object did not retain binding");
		errors.check(m_type.exists(id),
					 "Deleting bound object made its name invalid");
		errors.check(m_type.isDeleteFlagged(id),
					 "Deleting bound object did not flag the object for deletion");
		binder().bind(0);
	}
	else
	{
		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
		errors.check(binder().getBinding() == 0,
					 "Deleting bound object did not remove binding");
		errors.check(!m_type.exists(id),
					 "Deleting bound object did not make its name invalid");
		binder().bind(0);
	}

	errors.check(binder().getBinding() == 0, "Unbinding didn't remove binding");
	errors.check(!m_type.exists(id), "Name is still valid after deleting and unbinding");
}

void LifeTest::testBindNoGen (void)
{
	ResultCollector	errors	(getTestContext());
	const GLuint	id		= m_rnd.getUint32();

	if (!errors.check(!m_type.exists(id), "Randomly chosen identifier already exists"))
		return;

	Name			name	(m_type, id);
	binder().bind(*name);

	if (binder().genRequired())
	{
		errors.check(glGetError() == GL_INVALID_OPERATION,
					 "Did not fail when binding a name not generated by Gen* call");
		errors.check(!m_type.exists(*name),
					 "Bind* created an object for a name not generated by a Gen* call");
	}
	else
	{
		errors.check(glGetError() == GL_NO_ERROR,
					 "Failed when binding a name not generated by Gen* call");
		errors.check(m_type.exists(*name),
					 "Object was not created by the Bind* call");
	}
}

void LifeTest::testDeleteUsed (void)
{
	ResultCollector	errors(getTestContext());
	GLuint			programId = 0;

	{
		CheckedShader	vtxShader	(getRenderContext(),
									 SHADERTYPE_VERTEX, s_vertexShaderSrc);
		CheckedShader	fragShader	(getRenderContext(),
									 SHADERTYPE_FRAGMENT, s_fragmentShaderSrc);
		CheckedProgram	program		(getRenderContext(),
									 vtxShader.getShader(), fragShader.getShader());

		programId = program.getProgram();

		log() << TestLog::Message << "// Created and linked program " << programId
			  << TestLog::EndMessage;
		GLU_CHECK_CALL_ERROR(glUseProgram(programId), gl().getError());

		log() << TestLog::Message << "// Deleted program " << programId
			  << TestLog::EndMessage;
	}
	TCU_CHECK(glIsProgram(programId));
	{
		GLint deleteFlagged = 0;
		glGetProgramiv(programId, GL_DELETE_STATUS, &deleteFlagged);
		errors.check(deleteFlagged != 0, "Program object was not flagged as deleted");
	}
	GLU_CHECK_CALL_ERROR(glUseProgram(0), gl().getError());
	errors.check(!gl().isProgram(programId),
				 "Deleted program name still valid after being made non-current");
}

class AttachmentTest : public TestBase
{
public:
	typedef void			(AttachmentTest::*TestFunction)	(void);
							AttachmentTest					(const char*	name,
															 const char*	description,
															 Attacher&		attacher,
															 TestFunction	test)
								: TestBase		(name, description, attacher.getContext())
								, m_attacher	(attacher)
								, m_test		(test) {}
	IterateResult			iterate							(void);

	void					testDeletedNames				(void);
	void					testDeletedBinding				(void);
	void					testDeletedReattach				(void);

private:
	Attacher&				m_attacher;
	const TestFunction		m_test;
};

IterateResult AttachmentTest::iterate (void)
{
	(this->*m_test)();
	return STOP;
}

GLuint getAttachment (Attacher& attacher, GLuint container)
{
	const GLuint queriedAttachment = attacher.getAttachment(container);
	attacher.log() << TestLog::Message
				   << "// Result of query for " << attacher.getElementType().getName()
				   << " attached to " << attacher.getContainerType().getName() << " "
				   << container << ": " << queriedAttachment << "."
				   << TestLog::EndMessage;
	return queriedAttachment;
}

void AttachmentTest::testDeletedNames (void)
{
	Type&			elemType		= m_attacher.getElementType();
	Type&			containerType	= m_attacher.getContainerType();
	Name			container		(containerType);
	ResultCollector	errors			(getTestContext());
	GLuint			elementId		= 0;

	{
		Name element(elemType);
		elementId = *element;
		m_attacher.initAttachment(0, *element);
		m_attacher.attach(*element, *container);
		errors.check(getAttachment(m_attacher, *container) == elementId,
					 "Attachment name not returned by query even before deletion.");
	}

	// "Such a container or other context may continue using the object, and
	// may still contain state identifying its name as being currently bound"
	//
	// We here interpret "may" to mean that whenever the container has a
	// deleted object attached to it, a query will return that object's former
	// name.
	errors.check(getAttachment(m_attacher, *container) == elementId,
				 "Attachment name not returned by query after attachment was deleted.");

	if (elemType.nameLingers())
		errors.check(elemType.exists(elementId),
					 "Attached object name no longer valid after deletion.");
	else
		errors.check(!elemType.exists(elementId),
					 "Attached object name still valid after deletion.");

	m_attacher.detach(elementId, *container);
	errors.check(getAttachment(m_attacher, *container) == 0,
				 "Attachment name returned by query even after detachment.");
	errors.check(!elemType.exists(elementId),
				 "Deleted attached object name still usable after detachment.");
};

class InputAttachmentTest : public TestBase
{
public:
					InputAttachmentTest	(const char*	name,
										 const char*	description,
										 InputAttacher&	inputAttacher)
						: TestBase			(name, description, inputAttacher.getContext())
						, m_inputAttacher	(inputAttacher) {}

	IterateResult	iterate				(void);

private:
	InputAttacher&	m_inputAttacher;
};

GLuint replaceName (Type& type, GLuint oldName, TestLog& log)
{
	const Binder* const	binder		= type.binder();
	const bool			genRequired	= binder == DE_NULL || binder->genRequired();

	if (genRequired)
		return type.gen();

	log << TestLog::Message
		<< "// Type does not require Gen* for binding, reusing old id " << oldName << "."
		<< TestLog::EndMessage;

	return oldName;
}

IterateResult InputAttachmentTest::iterate (void)
{
	Attacher&		attacher		= m_inputAttacher.getAttacher();
	Type&			containerType	= attacher.getContainerType();
	Type&			elementType		= attacher.getElementType();
	Name			container		(containerType);
	GLuint			elementId		= 0;
	const GLuint	refSeed			= m_rnd.getUint32();
	const GLuint	newSeed			= m_rnd.getUint32();
	ResultCollector	errors			(getTestContext());

	Surface			refSurface;		// Surface from drawing with refSeed-seeded attachment
	Surface			delSurface;		// Surface from drawing with deleted refSeed attachment
	Surface			newSurface;		// Surface from drawing with newSeed-seeded attachment

	log() << TestLog::Message
		  << "Testing if writing to a newly created object modifies a deleted attachment"
		  << TestLog::EndMessage;

	{
		ScopedLogSection	section	(log(),
									 "Write to original", "Writing to an original attachment");
		const Name			element	(elementType);

		elementId = *element;
		attacher.initAttachment(refSeed, elementId);
		attacher.attach(elementId, *container);
		m_inputAttacher.drawContainer(*container, refSurface);
		// element gets deleted here
		log() << TestLog::Message << "// Deleting attachment";
	}
	{
		ScopedLogSection section	(log(), "Write to new",
									 "Writing to a new attachment after deleting the original");
		const GLuint	newId		= replaceName(elementType, elementId, log());
		const Name		newElement	(elementType, newId);

		attacher.initAttachment(newSeed, newId);

		m_inputAttacher.drawContainer(*container, delSurface);
		attacher.detach(elementId, *container);

		attacher.attach(newId, *container);
		m_inputAttacher.drawContainer(*container, newSurface);
		attacher.detach(newId, *container);
	}
	{
		const bool surfacesMatch = tcu::pixelThresholdCompare(
			log(), "Reading from deleted",
			"Comparison result from reading from a container with a deleted attachment "
			"before and after writing to a fresh object.",
			refSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

		errors.check(
			surfacesMatch,
			"Writing to a fresh object modified the container with a deleted attachment.");

		if (!surfacesMatch)
			log() << TestLog::Image("New attachment",
									"Container state after attached to the fresh object",
									newSurface);
	}

	return STOP;
}

class OutputAttachmentTest : public TestBase
{
public:
						OutputAttachmentTest			(const char*		name,
														 const char*		description,
														 OutputAttacher&	outputAttacher)
							: TestBase			(name, description,
												 outputAttacher.getContext())
							, m_outputAttacher	(outputAttacher) {}
	IterateResult		iterate							(void);

private:
	OutputAttacher&		m_outputAttacher;
};

IterateResult OutputAttachmentTest::iterate (void)
{
	Attacher&		attacher		= m_outputAttacher.getAttacher();
	Type&			containerType	= attacher.getContainerType();
	Type&			elementType		= attacher.getElementType();
	Name			container		(containerType);
	GLuint			elementId		= 0;
	const GLuint	refSeed			= m_rnd.getUint32();
	const GLuint	newSeed			= m_rnd.getUint32();
	ResultCollector	errors			(getTestContext());
	Surface			refSurface;		// Surface drawn from attachment to refSeed container
	Surface			newSurface;		// Surface drawn from attachment to newSeed container
	Surface			delSurface;		// Like newSurface, after writing to a deleted attachment

	log() << TestLog::Message
		  << "Testing if writing to a container with a deleted attachment "
		  << "modifies a newly created object"
		  << TestLog::EndMessage;

	{
		ScopedLogSection	section	(log(), "Write to existing",
									 "Writing to a container with an existing attachment");
		const Name			element	(elementType);

		elementId = *element;
		attacher.initAttachment(0, elementId);
		attacher.attach(elementId, *container);

		// For reference purposes, make note of what refSeed looks like.
		m_outputAttacher.setupContainer(refSeed, *container);
		m_outputAttacher.drawAttachment(elementId, refSurface);
	}
	{
		ScopedLogSection	section		(log(), "Write to deleted",
										 "Writing to a container after deletion of attachment");
		const GLuint		newId		= replaceName(elementType, elementId, log());
		const Name			newElement	(elementType, newId);

		log() << TestLog::Message
			  << "Creating a new object " << newId
			  << TestLog::EndMessage;

		log() << TestLog::Message
			  << "Recording state of new object before writing to container"
			  << TestLog::EndMessage;
		attacher.initAttachment(newSeed, newId);
		m_outputAttacher.drawAttachment(newId, newSurface);

		log() << TestLog::Message
			  << "Writing to container"
			  << TestLog::EndMessage;

		// Now re-write refSeed to the container.
		m_outputAttacher.setupContainer(refSeed, *container);
		// Does it affect the newly created attachment object?
		m_outputAttacher.drawAttachment(newId, delSurface);
	}
	attacher.detach(elementId, *container);

	const bool surfacesMatch = tcu::pixelThresholdCompare(
		log(), "Writing to deleted",
		"Comparison result from reading from a fresh object before and after "
		"writing to a container with a deleted attachment",
		newSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

	errors.check(surfacesMatch,
				 "Writing to container with deleted attachment modified a new object.");

	if (!surfacesMatch)
		log() << TestLog::Image(
			"Original attachment",
			"Result of container modification on original attachment before deletion.",
			refSurface);
	return STOP;
};

struct LifeTestSpec
{
	const char*				name;
	LifeTest::TestFunction	func;
	bool					needBind;
};

MovePtr<TestCaseGroup> createLifeTestGroup (TestContext& testCtx,
											const LifeTestSpec& spec,
											const vector<Type*>& types)
{
	MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, spec.name, spec.name));

	for (vector<Type*>::const_iterator it = types.begin(); it != types.end(); ++it)
	{
		Type& type = **it;
		const char* name = type.getName();
		if (!spec.needBind || type.binder() != DE_NULL)
			group->addChild(new LifeTest(name, name, type, spec.func));
	}

	return group;
}

static const LifeTestSpec s_lifeTests[] =
{
	{ "gen",			&LifeTest::testGen,			false	},
	{ "delete",			&LifeTest::testDelete,		false	},
	{ "bind",			&LifeTest::testBind,		true	},
	{ "delete_bound",	&LifeTest::testDeleteBound,	true	},
	{ "bind_no_gen",	&LifeTest::testBindNoGen,	true	},
};

string attacherName (Attacher& attacher)
{
	ostringstream os;
	os << attacher.getElementType().getName() << "_" <<  attacher.getContainerType().getName();
	return os.str();
}

void addTestCases (TestCaseGroup& group, Types& types)
{
	TestContext& testCtx = types.getTestContext();

	for (const LifeTestSpec* it = DE_ARRAY_BEGIN(s_lifeTests);
		 it != DE_ARRAY_END(s_lifeTests); ++it)
		group.addChild(createLifeTestGroup(testCtx, *it, types.getTypes()).release());

	{
		TestCaseGroup* const delUsedGroup =
			new TestCaseGroup(testCtx, "delete_used", "Delete current program");
		group.addChild(delUsedGroup);

		delUsedGroup->addChild(
			new LifeTest("program", "program", types.getProgramType(),
						 &LifeTest::testDeleteUsed));
	}

	{
		TestCaseGroup* const	attGroup	= new TestCaseGroup(
			testCtx, "attach", "Attachment tests");
		group.addChild(attGroup);

		{
			TestCaseGroup* const	nameGroup	= new TestCaseGroup(
				testCtx, "deleted_name", "Name of deleted attachment");
			attGroup->addChild(nameGroup);

			const vector<Attacher*>& atts = types.getAttachers();
			for (vector<Attacher*>::const_iterator it = atts.begin(); it != atts.end(); ++it)
			{
				const string name = attacherName(**it);
				nameGroup->addChild(new AttachmentTest(name.c_str(), name.c_str(), **it,
													   &AttachmentTest::testDeletedNames));
			}
		}
		{
			TestCaseGroup* inputGroup = new TestCaseGroup(
				testCtx, "deleted_input", "Input from deleted attachment");
			attGroup->addChild(inputGroup);

			const vector<InputAttacher*>& inAtts = types.getInputAttachers();
			for (vector<InputAttacher*>::const_iterator it = inAtts.begin();
				 it != inAtts.end(); ++it)
			{
				const string name = attacherName((*it)->getAttacher());
				inputGroup->addChild(new InputAttachmentTest(name.c_str(), name.c_str(), **it));
			}
		}
		{
			TestCaseGroup* outputGroup = new TestCaseGroup(
				testCtx, "deleted_output", "Output to deleted attachment");
			attGroup->addChild(outputGroup);

			const vector<OutputAttacher*>& outAtts = types.getOutputAttachers();
			for (vector<OutputAttacher*>::const_iterator it = outAtts.begin();
				 it != outAtts.end(); ++it)
			{
				string name = attacherName((*it)->getAttacher());
				outputGroup->addChild(new OutputAttachmentTest(name.c_str(), name.c_str(),
															   **it));
			}
		}
	}
}

} // details
} // LifetimeTests
} // gls
} // deqp
