/*-------------------------------------------------------------------------
 * 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());
	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());

	GLuint ret = GLenum(type) == requiredType ? name : 0;
	return ret;
}

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, width - maxWidth);
	const GLint			height	= de::min(target.getHeight(), maxHeight);
	const GLint			yOff	= rnd.getInt(0, height - maxHeight);

	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
