#ifndef _TCUTESTLOG_HPP
#define _TCUTESTLOG_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 Test Log C++ Wrapper.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "qpTestLog.h"
#include "tcuTexture.hpp"

#include <sstream>

namespace tcu
{

class Surface;
class MessageBuilder;
class LogImageSet;
class LogImage;
class LogSection;
class LogShaderProgram;
class LogShader;
class LogKernelSource;
class LogSampleList;
class LogValueInfo;
class SampleBuilder;
template<typename T> class LogNumber;

/*--------------------------------------------------------------------*//*!
 * \brief Test log
 *
 * TestLog provides convinient C++ API for logging. The API has been designed
 * around stream operators much like STL iostream library. The following
 * examples demonstrate how to use TestLog.
 *
 * \code
 * TestLog& log = m_testCtx.getLog();
 *
 * // Write message to log.
 * log << TestLog::Message << "Hello, World!" << TestLog::EndMessage;
 * int myNumber = 3;
 * log << TestLog::Message << "Diff is " << myNumber << TestLog::EndMessage;
 *
 * // Write image
 * Surface myImage(256, 256);
 * log << TestLog::Image("TestImage", "My test image", myImage);
 *
 * // Multiple commands can be combined:
 * log << TestLog::Section("Details", "Test case details")
 *     << TestLog::Message << "Here be dragons" << TestLog::EndMessage
 *     << TestLog::ImageSet("Result", "Result images")
 *     << TestLog::Image("ImageA", "Image A", imageA)
 *     << TestLog::Image("ImageB", "Image B", imageB)
 *     << TestLog::EndImageSet << TestLog::EndSection;
 * \endcode
 *//*--------------------------------------------------------------------*/
class TestLog
{
public:
	// Tokens
	static const class BeginMessageToken {}			Message;
	static const class EndMessageToken {}			EndMessage;
	static const class EndImageSetToken {}			EndImageSet;
	static const class EndSectionToken {}			EndSection;
	static const class EndShaderProgramToken {}		EndShaderProgram;
	static const class SampleInfoToken {}			SampleInfo;
	static const class EndSampleInfoToken {}		EndSampleInfo;
	static const class BeginSampleToken {}			Sample;
	static const class EndSampleToken {}			EndSample;
	static const class EndSampleListToken {}		EndSampleList;

	// Typedefs.
	typedef LogImageSet			ImageSet;
	typedef LogImage			Image;
	typedef LogSection			Section;
	typedef LogShaderProgram	ShaderProgram;
	typedef LogShader			Shader;
	typedef LogKernelSource		KernelSource;
	typedef LogSampleList		SampleList;
	typedef LogValueInfo		ValueInfo;
	typedef LogNumber<float>	Float;
	typedef LogNumber<deInt64>	Integer;

	explicit			TestLog					(const char* fileName, deUint32 flags = 0);
						~TestLog				(void);

	MessageBuilder		operator<<				(const BeginMessageToken&);
	MessageBuilder		message					(void);

	TestLog&			operator<<				(const ImageSet& imageSet);
	TestLog&			operator<<				(const Image& image);
	TestLog&			operator<<				(const EndImageSetToken&);

	TestLog&			operator<<				(const Section& section);
	TestLog&			operator<<				(const EndSectionToken&);

	TestLog&			operator<<				(const ShaderProgram& shaderProgram);
	TestLog&			operator<<				(const EndShaderProgramToken&);
	TestLog&			operator<<				(const Shader& shader);

	TestLog&			operator<<				(const KernelSource& kernelSrc);

	template<typename T>
	TestLog&			operator<<				(const LogNumber<T>& number);

	TestLog&			operator<<				(const SampleList& sampleList);
	TestLog&			operator<<				(const SampleInfoToken&);
	TestLog&			operator<<				(const ValueInfo& valueInfo);
	TestLog&			operator<<				(const EndSampleInfoToken&);
	SampleBuilder		operator<<				(const BeginSampleToken&);
	TestLog&			operator<<				(const EndSampleListToken&);

	// Raw api
	void				writeMessage			(const char* message);

	void				startImageSet			(const char* name, const char* description);
	void				endImageSet				(void);
	void				writeImage				(const char* name, const char* description, const ConstPixelBufferAccess& surface, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compressionMode = QP_IMAGE_COMPRESSION_MODE_BEST);
	void				writeImage				(const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data);

	void				startSection			(const char* name, const char* description);
	void				endSection				(void);

	void				startShaderProgram		(bool linkOk, const char* linkInfoLog);
	void				endShaderProgram		(void);
	void				writeShader				(qpShaderType type, const char* source, bool compileOk, const char* infoLog);

	void				writeKernelSource		(const char* source);
	void				writeCompileInfo		(const char* name, const char* description, bool compileOk, const char* infoLog);

	void				writeFloat				(const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value);
	void				writeInteger			(const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value);

	void				startEglConfigSet		(const char* name, const char* description);
	void				writeEglConfig			(const qpEglConfigInfo* config);
	void				endEglConfigSet			(void);

	void				startCase				(const char* testCasePath, qpTestCaseType testCaseType);
	void				endCase					(qpTestResult result, const char* description);
	void				terminateCase			(qpTestResult result);

	void				startSampleList			(const std::string& name, const std::string& description);
	void				startSampleInfo			(void);
	void				writeValueInfo			(const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag);
	void				endSampleInfo			(void);
	void				startSample				(void);
	void				writeSampleValue		(double value);
	void				writeSampleValue		(deInt64 value);
	void				endSample				(void);
	void				endSampleList			(void);

private:
						TestLog					(const TestLog& other); // Not allowed!
	TestLog&			operator=				(const TestLog& other); // Not allowed!

	qpTestLog*			m_log;
};

class MessageBuilder
{
public:
	explicit				MessageBuilder		(TestLog* log) : m_log(log) {}
							~MessageBuilder		(void) {}

	std::string				toString			(void) const { return m_str.str(); }

	TestLog&				operator<<			(const TestLog::EndMessageToken&);

	template <typename T>
	MessageBuilder&			operator<<			(const T& value);

							MessageBuilder		(const MessageBuilder& other);
	MessageBuilder&			operator=			(const MessageBuilder& other);

private:
	TestLog*				m_log;
	std::ostringstream		m_str;
};

class SampleBuilder
{
public:
							SampleBuilder		(TestLog* log) : m_log(log) {}

	SampleBuilder&			operator<<			(int v)		{ m_values.push_back(Value((deInt64)v));	return *this; }
	SampleBuilder&			operator<<			(deInt64 v)	{ m_values.push_back(Value(v));				return *this; }
	SampleBuilder&			operator<<			(float v)	{ m_values.push_back(Value((double)v));		return *this; }
	SampleBuilder&			operator<<			(double v)	{ m_values.push_back(Value(v));				return *this; }

	TestLog&				operator<<			(const TestLog::EndSampleToken&);

private:
	struct Value
	{
		enum Type { TYPE_INT64 = 0, TYPE_FLOAT64, TYPE_LAST };

		Type	type;
		union
		{
			deInt64		int64;
			double		float64;
		} value;

		Value (void)		: type(TYPE_LAST)		{ value.int64 = 0;		}
		Value (double v)	: type(TYPE_FLOAT64)	{ value.float64 = v;	}
		Value (deInt64 v)	: type(TYPE_INT64)		{ value.int64 = v;		}
	};

	TestLog*				m_log;
	std::vector<Value>		m_values;
};

class LogImageSet
{
public:
	LogImageSet (const std::string& name, const std::string& description)
		: m_name		(name)
		, m_description	(description)
	{
	}

	void write (TestLog& log) const;

private:
	std::string		m_name;
	std::string		m_description;
};

// \note Doesn't take copy of surface contents
class LogImage
{
public:
	LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);

	LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);

	LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST)
		: m_name		(name)
		, m_description	(description)
		, m_access		(access)
		, m_scale		(scale)
		, m_bias		(bias)
		, m_compression	(compression)
	{
	}

	void write (TestLog& log) const;

private:
	std::string				m_name;
	std::string				m_description;
	ConstPixelBufferAccess	m_access;
	Vec4					m_scale;
	Vec4					m_bias;
	qpImageCompressionMode	m_compression;
};

class LogSection
{
public:
	LogSection (const std::string& name, const std::string& description)
		: m_name		(name)
		, m_description	(description)
	{
	}

	void write (TestLog& log) const;

private:
	std::string		m_name;
	std::string		m_description;
};

class LogShaderProgram
{
public:
	LogShaderProgram (bool linkOk, const std::string& linkInfoLog)
		: m_linkOk		(linkOk)
		, m_linkInfoLog	(linkInfoLog)
	{
	}

	void write (TestLog& log) const;

private:
	bool			m_linkOk;
	std::string		m_linkInfoLog;
};

class LogShader
{
public:
	LogShader (qpShaderType type, const std::string& source, bool compileOk, const std::string& infoLog)
		: m_type		(type)
		, m_source		(source)
		, m_compileOk	(compileOk)
		, m_infoLog		(infoLog)
	{
	}

	void write (TestLog& log) const;

private:
	qpShaderType	m_type;
	std::string		m_source;
	bool			m_compileOk;
	std::string		m_infoLog;
};

class LogKernelSource
{
public:
	explicit LogKernelSource (const std::string& source)
		: m_source(source)
	{
	}

	void write (TestLog& log) const;

private:
	std::string	m_source;
};

class LogSampleList
{
public:
	LogSampleList (const std::string& name, const std::string& description)
		: m_name		(name)
		, m_description	(description)
	{
	}

	void write (TestLog& log) const;

private:
	std::string		m_name;
	std::string		m_description;
};

class LogValueInfo
{
public:
	LogValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag)
		: m_name		(name)
		, m_description	(description)
		, m_unit		(unit)
		, m_tag			(tag)
	{
	}

	void write (TestLog& log) const;

private:
	std::string			m_name;
	std::string			m_description;
	std::string			m_unit;
	qpSampleValueTag	m_tag;
};

template<typename T>
class LogNumber
{
public:
	LogNumber (const std::string& name, const std::string& desc, const std::string& unit, qpKeyValueTag tag, T value)
		: m_name	(name)
		, m_desc	(desc)
		, m_unit	(unit)
		, m_tag		(tag)
		, m_value	(value)
	{
	}

	void write (TestLog& log) const;

private:
	std::string		m_name;
	std::string		m_desc;
	std::string		m_unit;
	qpKeyValueTag	m_tag;
	T				m_value;
};

// Section helper that closes section when leaving scope.
class ScopedLogSection
{
public:
	ScopedLogSection (TestLog& log, const std::string& name, const std::string& description)
		: m_log(log)
	{
		m_log << TestLog::Section(name, description);
	}

	~ScopedLogSection (void)
	{
		m_log << TestLog::EndSection;
	}

private:
	TestLog& m_log;
};

// TestLog stream operators.

inline TestLog& TestLog::operator<< (const ImageSet& imageSet)			{ imageSet.write(*this);	return *this;	}
inline TestLog& TestLog::operator<< (const Image& image)				{ image.write(*this);		return *this;	}
inline TestLog& TestLog::operator<< (const EndImageSetToken&)			{ endImageSet();			return *this;	}
inline TestLog& TestLog::operator<< (const Section& section)			{ section.write(*this);		return *this;	}
inline TestLog& TestLog::operator<< (const EndSectionToken&)			{ endSection();				return *this;	}
inline TestLog& TestLog::operator<< (const ShaderProgram& shaderProg)	{ shaderProg.write(*this);	return *this;	}
inline TestLog& TestLog::operator<< (const EndShaderProgramToken&)		{ endShaderProgram();		return *this;	}
inline TestLog& TestLog::operator<< (const Shader& shader)				{ shader.write(*this);		return *this;	}
inline TestLog& TestLog::operator<< (const KernelSource& kernelSrc)		{ kernelSrc.write(*this);	return *this;	}
inline TestLog&	TestLog::operator<<	(const SampleList& sampleList)		{ sampleList.write(*this);	return *this;	}
inline TestLog&	TestLog::operator<<	(const SampleInfoToken&)			{ startSampleInfo();		return *this;	}
inline TestLog&	TestLog::operator<<	(const ValueInfo& valueInfo)		{ valueInfo.write(*this);	return *this;	}
inline TestLog&	TestLog::operator<<	(const EndSampleInfoToken&)			{ endSampleInfo();			return *this;	}
inline TestLog&	TestLog::operator<<	(const EndSampleListToken&)			{ endSampleList();			return *this;	}

template<typename T>
inline TestLog& TestLog::operator<< (const LogNumber<T>& number)
{
	number.write(*this);
	return *this;
}

inline TestLog& operator<< (TestLog& log, const std::exception& e)
{
	// \todo [2012-10-18 pyry] Print type info?
	return log << TestLog::Message << e.what() << TestLog::EndMessage;
}

// Utility class inline implementations.

template <typename T>
inline MessageBuilder& MessageBuilder::operator<< (const T& value)
{
	// Overload stream operator to implement custom format
	m_str << value;
	return *this;
}

inline MessageBuilder TestLog::operator<< (const BeginMessageToken&)
{
	return MessageBuilder(this);
}

inline MessageBuilder TestLog::message (void)
{
	return MessageBuilder(this);
}

inline SampleBuilder TestLog::operator<< (const BeginSampleToken&)
{
	return SampleBuilder(this);
}

inline void LogImageSet::write (TestLog& log) const
{
	log.startImageSet(m_name.c_str(), m_description.c_str());
}

inline void LogImage::write (TestLog& log) const
{
	log.writeImage(m_name.c_str(), m_description.c_str(), m_access, m_scale, m_bias, m_compression);
}

inline void LogSection::write (TestLog& log) const
{
	log.startSection(m_name.c_str(), m_description.c_str());
}

inline void LogShaderProgram::write (TestLog& log) const
{
	log.startShaderProgram(m_linkOk, m_linkInfoLog.c_str());
}

inline void LogShader::write (TestLog& log) const
{
	log.writeShader(m_type, m_source.c_str(), m_compileOk, m_infoLog.c_str());
}

inline void LogKernelSource::write (TestLog& log) const
{
	log.writeKernelSource(m_source.c_str());
}

inline void LogSampleList::write (TestLog& log) const
{
	log.startSampleList(m_name, m_description);
}

inline void LogValueInfo::write (TestLog& log) const
{
	log.writeValueInfo(m_name, m_description, m_unit, m_tag);
}

template<>
inline void LogNumber<float>::write (TestLog& log) const
{
	log.writeFloat(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
}

template<>
inline void LogNumber<deInt64>::write (TestLog& log) const
{
	log.writeInteger(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
}

} // tcu

#endif // _TCUTESTLOG_HPP
