#ifndef _TCUTHREADUTIL_HPP
#define _TCUTHREADUTIL_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 Thread test utilities
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "deSharedPtr.hpp"
#include "deMutex.hpp"
#include "deSemaphore.hpp"
#include "deThread.hpp"
#include "deRandom.hpp"

#include <vector>
#include <sstream>

namespace tcu
{
namespace ThreadUtil
{
// Event object for synchronizing threads
class Event
{
public:
	enum Result
	{
		RESULT_NOT_READY = 0,
		RESULT_OK,
		RESULT_FAILED
	};

					Event 		(void);
					~Event		(void);
	void			setResult	(Result result);
	Result			waitReady	(void);
	Result			getResult	(void) const { return m_result; }

private:
	volatile Result	m_result;
	volatile int	m_waiterCount;
	de::Semaphore	m_waiters;
	de::Mutex		m_lock;

	// Disabled
					Event		(const Event&);
	Event&			operator=	(const Event&);
};

// Base class for objects which modifications should be tracked between threads
class Object
{
public:
										Object		(const char* type, de::SharedPtr<Event> createEvent);
	virtual								~Object		(void);
	const char*							getType		(void) const { return m_type; }

	// Used by class Operation only
	void								read		(de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event> >& deps);
	void								modify		(de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event> >& deps);

private:
	const char*							m_type;
	de::SharedPtr<Event>				m_modify;
	std::vector<de::SharedPtr<Event> >	m_reads;

	// Disabled
										Object		(const Object&);
	Object&								operator=	(const Object&);
};

class Thread;

class MessageBuilder
{
public:
						MessageBuilder		(Thread& thread) : m_thread(thread) {}
						MessageBuilder		(const MessageBuilder& other) : m_thread(other.m_thread), m_stream(other.m_stream.str()) {}
	template<class T>
	MessageBuilder&		operator<<			(const T& t) { m_stream << t; return *this; }

	class EndToken
	{
	public:
						EndToken			(void) {}
	};

	void 				operator<<			(const EndToken&);

private:
	Thread&				m_thread;
	std::stringstream	m_stream;
};

class Message
{
public:
						Message		(deUint64 time, const char* message) : m_time(time), m_message(message) {}

	deUint64			getTime		(void) const { return m_time; }
	const std::string&	getMessage	(void) const { return m_message; }

	static const MessageBuilder::EndToken End;

private:
	deUint64			m_time;
	std::string			m_message;
};

// Base class for operations executed by threads
class Operation
{
public:
											Operation		(const char* name);
	virtual									~Operation		(void);

	const char*								getName			(void) const { return m_name; }
	de::SharedPtr<Event>					getEvent		(void) { return m_event; }

	void									readObject		(de::SharedPtr<Object> object) { object->read(m_event, m_deps); }
	void									modifyObject	(de::SharedPtr<Object> object) { object->modify(m_event, m_deps); }

	virtual void							exec			(Thread& thread) = 0;	//!< Overwritten by inherited class to perform actual operation
	virtual void							execute			(Thread& thread);		//!< May Be overwritten by inherited class to change how syncronization is done

protected:
	const char*								m_name;
	std::vector<de::SharedPtr<Event> >		m_deps;
	de::SharedPtr<Event>					m_event;

											Operation		(const Operation&);
	Operation&								operator=		(const Operation&);
};

class Thread : public de::Thread
{
public:
	enum ThreadStatus
	{
		THREADSTATUS_NOT_STARTED = 0,
		THREADSTATUS_INIT_FAILED,
		THREADSTATUS_RUNNING,
		THREADSTATUS_READY,
		THREADSTATUS_FAILED,
		THREADSTATUS_NOT_SUPPORTED
	};
							Thread				(deUint32 seed);
							~Thread				(void);

	virtual void			init				(void) {}	//!< Called first before any Operation

	// \todo [mika] Should the result of execution be passed to deinit?
	virtual void			deinit				(void) {}	//!< Called after after operation

	void					addOperation		(Operation* operation);

	void					exec				(void);

	deUint8*				getDummyData		(size_t size);	//!< Return data pointer that contains at least size bytes. Valid until next call

	ThreadStatus			getStatus			(void) const { return m_status; }

	MessageBuilder			newMessage			(void) { return MessageBuilder(*this); }
	de::Random&				getRandom			(void) { return m_random; }

	// Used to by test case to read log messages
	int						getMessageCount		(void) const;
	Message					getMessage			(int index) const;

	// Used by message builder
	void					pushMessage			(const std::string& str);

private:
	virtual void			run					(void);

	std::vector<Operation*>	m_operations;
	de::Random				m_random;

	mutable de::Mutex		m_messageLock;
	std::vector<Message>	m_messages;
	ThreadStatus			m_status;
	std::vector<deUint8>	m_dummyData;

	// Disabled
							Thread				(const Thread&);
	Thread					operator=			(const Thread&);
};

class DataBlock : public Object
{
public:
					DataBlock	(de::SharedPtr<Event> event);

	void			setData		(size_t size, const void* data);
	const deUint8*	getData		(void) const { return &(m_data[0]); }
	size_t			getSize		(void) const { return m_data.size(); }

private:
	std::vector<deUint8> m_data;
};


class CompareData : public Operation
{
public:
			CompareData	(de::SharedPtr<DataBlock> a, de::SharedPtr<DataBlock> b);
	void	exec		(Thread& thread);

private:
	de::SharedPtr<DataBlock>	m_a;
	de::SharedPtr<DataBlock>	m_b;
};

} // ThreadUtil
} // tcu

#endif // _TCUTHREADUTIL_HPP
