// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>



#include <cassert>
#include <ctime>



#if defined(XALAN_OLD_STREAM_HEADERS)
#include <iostream.h>
#else
#include <iostream>
#endif



#include <util/PlatformUtils.hpp>
#include <util/Mutexes.hpp>



#include <Include/XalanAutoPtr.hpp>



#include <XalanTransformer/XalanTransformer.hpp>



#if defined(WIN32)
//This is here for the threads.
#include <process.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(XALAN_POSIX2_AVAILABLE)
#include <pthread.h>
#include <unistd.h>
#else
#error Unsupported platform!
#endif



#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
#endif


	
// This is here for memory leak testing.
#if defined(_DEBUG)
#include <crtdbg.h>
#endif


	
class SynchronizedCounter
{
public:

	SynchronizedCounter();

	~SynchronizedCounter();

	void
	increment();

	void
	decrement();

	unsigned long
	getCounter() const;

private:

	mutable XMLMutex	m_mutex;

	unsigned long		m_counter;
};



SynchronizedCounter::SynchronizedCounter() :
	m_mutex(),
	m_counter(0)
{
}



SynchronizedCounter::~SynchronizedCounter()
{
}



void
SynchronizedCounter::increment()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter < ULONG_MAX)
	{
		++m_counter;
	}
}



void
SynchronizedCounter::decrement()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter > 0)
	{
		--m_counter;
	}
}



unsigned long
SynchronizedCounter::getCounter() const
{
	return m_counter;
}



struct
ThreadInfo
{
	ThreadInfo(
			unsigned int			theThreadNumber = 0,
			SynchronizedCounter*	theCounter = 0) :
		m_threadNumber(theThreadNumber),
		m_counter(theCounter)
	{
	}

	unsigned int			m_threadNumber;

	SynchronizedCounter*	m_counter;
};



// Used to hold compiled stylesheet and pre-parsed source...
const XalanCompiledStylesheet*	glbCompiledStylesheet = 0;
const XalanParsedSource*		glbParsedSource = 0;



#if defined(WIN32)

extern "C" void theThreadRoutine(void* param);

void
#elif defined(XALAN_POSIX2_AVAILABLE)

extern "C" void* theThreadRoutine(void* param);

void*
#else
#error Unsupported platform!
#endif
theThreadRoutine(void*		param)
{
// This routine uses compiled stylesheet (glbStylesheetRoot), which is set using the 
// theProcessor.setStylesheetRoot method. The transform is done using the theProcessor's
// process() method.

#if defined(XALAN_OLD_STYLE_CASTS)
	const ThreadInfo* const		theInfo = (const ThreadInfo*)param;
#else
	const ThreadInfo* const		theInfo = reinterpret_cast<const ThreadInfo*>(param);
#endif

	assert(theInfo != 0);

	theInfo->m_counter->increment();

	try
	{
		// Our input file.  The assumption is that the executable will be run
		// from same directory as the input files.

		// Generate the output file name.
		const XalanDOMString	theOutputFile(
				XalanDOMString("birds") +
				UnsignedLongToDOMString(theInfo->m_threadNumber) +
				XalanDOMString(".out"));

		// Create a transformer...
		XalanTransformer	theTransformer;

		// Do the transform...
		theTransformer.transform(*glbParsedSource, glbCompiledStylesheet, XSLTResultTarget(theOutputFile));
	}
	catch(...)
	{
		cerr << "Exception caught in thread " << theInfo->m_threadNumber;
	}

	// Decrement the counter because we're done...
	theInfo->m_counter->decrement();

#if defined(XALAN_POSIX2_AVAILABLE)
	return 0;
#endif
}



inline void
doSleep(unsigned int	theMilliseconds)
{
#if defined(WIN32)
	Sleep(theMilliseconds);
#elif defined(XALAN_POSIX2_AVAILABLE)
	usleep(theMilliseconds * 10);
#else
#error Unsupported platform!
#endif
}



void
doThreads(long	theThreadCount)
{
	cout << endl << "Starting " << theThreadCount << " threads." << endl;

	XalanArrayAutoPtr<ThreadInfo>	theThreadInfo(new ThreadInfo[theThreadCount]);

	try
	{
		cout << endl << "Clock before starting threads: " << clock() << endl;

		SynchronizedCounter		theCounter;

		long	i = 0;

		while (i < theThreadCount)
		{
			theThreadInfo[i].m_threadNumber = i;
			theThreadInfo[i].m_counter = &theCounter;

#if defined(WIN32)

			const unsigned long		theThreadID =
					_beginthread(theThreadRoutine, 4096, reinterpret_cast<LPVOID>(&theThreadInfo[i]));

			if (theThreadID == unsigned(-1))
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}

#elif defined(XALAN_POSIX2_AVAILABLE)

			pthread_t	theThread;

			const int	theResult = pthread_create(&theThread, 0, theThreadRoutine, (void*)&theThreadInfo[i]);

			if (theResult != 0)
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}
			else
			{
#if defined(OS390)
				pthread_detach(&theThread);
#else
				pthread_detach(theThread);
#endif
			}
#else
#error Unsupported platform!
#endif

			++i;
		}

		clock_t		theClock = 0;

		if (i == 0)
		{
			cerr << endl << "No threads were created!" << endl;
		}
		else
		{
			unsigned int	theCheckCount = 0;

			do
			{
				doSleep(2000);

				// Check a couple of times, just in case, since
				// getCounter() is not synchronized...
				if (theCounter.getCounter() == 0)
				{
					if (theCheckCount == 0)
					{
						theClock = clock();
					}

					++theCheckCount;
				}
			}
			while(theCheckCount < 2);
		}

		cout << endl << "Clock after threads: " << theClock << endl;
	}
	catch(...)
	{
		cerr << "Exception caught!!!"
			 << endl
			<< endl;
	}
}


int
main(
			int				argc,
			const char*		argv[])
{
#if !defined(NDEBUG) && defined(_MSC_VER)
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

	_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif

	if (argc > 2)
	{
		cerr << "Usage: ThreadTest"
			 << endl
			 << endl;
	}
	else
	{
		int		threadCount = 60;

		if (argc == 2)
		{
			threadCount = atoi(argv[1]);
		}

		try
		{
			// Initialize Xerces...
			XMLPlatformUtils::Initialize();

			// Initialize Xalan...
			XalanTransformer::initialize();

			{
				// Create a XalanTransformer.  We won't actually use this to transform --
				// it's just acting likely a factory for the compiled stylesheet and
				// pre-parsed source.
				XalanTransformer	theXalanTransformer;

				const char* const	theXSLFileName = "birds.xsl";

				theXalanTransformer.compileStylesheet(theXSLFileName, glbCompiledStylesheet);
				assert(glbCompiledStylesheet != 0);

				// Compile the XML source document as well. All threads will use
				// this binary representation of the source tree.
				const char* const	theXMLFileName = "birds.xml";

				theXalanTransformer.parseSource(theXMLFileName, glbParsedSource);
				assert(glbParsedSource != 0);

				doThreads(threadCount);
			}

			// Terminate Xalan...
			XalanTransformer::terminate();

			// Terminate Xerces...
			XMLPlatformUtils::Terminate();
		}
		catch(...)
		{
			cerr << "Exception caught!!!"
				 << endl
				 << endl;
		}

	} 

	return 0;
}
