/*-------------------------------------------------------------------------
 * 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
