#ifndef _XSWIN32TESTPROCESS_HPP
#define _XSWIN32TESTPROCESS_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Execution Server
 * ---------------------------------------------
 *
 * 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 TestProcess implementation for Win32.
 *//*--------------------------------------------------------------------*/

#include "xsDefs.hpp"
#include "xsTestProcess.hpp"
#include "deThread.hpp"

#include <vector>
#include <string>

#if !defined(VC_EXTRALEAN)
#	define VC_EXTRALEAN 1
#endif
#if !defined(WIN32_LEAN_AND_MEAN)
#	define WIN32_LEAN_AND_MEAN 1
#endif
#if !defined(NOMINMAX)
#	define NOMINMAX 1
#endif
#include <windows.h>

namespace xs
{
namespace win32
{

class Error : public std::runtime_error
{
public:
							Error				(DWORD error, const char* msg);

private:
	DWORD					m_error;
};

class Event
{
public:
							Event				(bool manualReset, bool initialState);
							~Event				(void);

	void					setSignaled			(void);
	void					reset				(void);

	HANDLE					getHandle			(void) const { return m_handle; }

private:
							Event				(const Event& other);
	Event&					operator=			(const Event& other);

	HANDLE					m_handle;
};

class CaseListWriter : public de::Thread
{
public:
							CaseListWriter		(void);
							~CaseListWriter		(void);

	void					start				(const char* caseList, HANDLE dst);
	void					stop				(void);

	void					run					(void);

private:
	std::vector<char>		m_caseList;
	HANDLE					m_dst;
	Event					m_cancelEvent;
};

class FileReader : public de::Thread
{
public:
							FileReader			(ThreadedByteBuffer* dst);
							~FileReader			(void);

	void					start				(HANDLE file);
	void					stop				(void);

	void					run					(void);

private:
	ThreadedByteBuffer*		m_dstBuf;
	HANDLE					m_handle;
	Event					m_cancelEvent;
};

class TestLogReader
{
public:
							TestLogReader		(void);
							~TestLogReader		(void);

	void					start				(const char* filename);
	void					stop				(void);

	bool					isRunning			(void) const					{ return m_reader.isStarted();					}

	int						read				(deUint8* dst, int numBytes)	{ return m_logBuffer.tryRead(numBytes, dst);	}

private:
	ThreadedByteBuffer		m_logBuffer;
	HANDLE					m_logFile;

	FileReader				m_reader;
};

// \note deProcess uses anonymous pipes that don't have overlapped IO available.
//		 For ExecServer purposes we need overlapped IO, and it makes the handles
//		 incompatible with deFile. Thus separate Process implementation is used for now.
class Process
{
public:
							Process				(void);
							~Process			(void);

	void					start				(const char* commandLine, const char* workingDirectory);

	void					waitForFinish		(void);
	void					terminate			(void);
	void					kill				(void);

	bool					isRunning			(void);
	int						getExitCode			(void) const { return m_exitCode;		}

	HANDLE					getStdIn			(void) const { return m_standardIn;		}
	HANDLE					getStdOut			(void) const { return m_standardOut;	}
	HANDLE					getStdErr			(void) const { return m_standardErr;	}

private:
							Process				(const Process& other);
	Process&				operator=			(const Process& other);

	void					stopProcess			(bool kill);
	void					cleanupHandles		(void);

	enum State
	{
		STATE_NOT_STARTED = 0,
		STATE_RUNNING,
		STATE_FINISHED,

		STATE_LAST
	};

	State					m_state;
	int						m_exitCode;

	PROCESS_INFORMATION		m_procInfo;
	HANDLE					m_standardIn;
	HANDLE					m_standardOut;
	HANDLE					m_standardErr;
};

} // win32

class Win32TestProcess : public TestProcess
{
public:
							Win32TestProcess		(void);
	virtual					~Win32TestProcess		(void);

	virtual void			start					(const char* name, const char* params, const char* workingDir, const char* caseList);
	virtual void			terminate				(void);
	virtual void			cleanup					(void);

	virtual bool			isRunning				(void);
	virtual int				getExitCode				(void) const;

	virtual int				readTestLog				(deUint8* dst, int numBytes);
	virtual int				readInfoLog				(deUint8* dst, int numBytes) { return m_infoBuffer.tryRead(numBytes, dst); }

private:
							Win32TestProcess		(const Win32TestProcess& other);
	Win32TestProcess&		operator=				(const Win32TestProcess& other);

	win32::Process*			m_process;
	deUint64				m_processStartTime;
	std::string				m_logFileName;

	ThreadedByteBuffer		m_infoBuffer;

	// Threads.
	win32::CaseListWriter	m_caseListWriter;
	win32::FileReader		m_stdOutReader;
	win32::FileReader		m_stdErrReader;
	win32::TestLogReader	m_testLogReader;
};

} // xs

#endif // _XSWIN32TESTPROCESS_HPP
