#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 { de::ScopedLock lock(m_statusLock); return m_status; }
	void				setStatus			(ThreadStatus status) { de::ScopedLock lock(m_statusLock); m_status = 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;
	mutable de::Mutex		m_statusLock;
	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
