#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
