/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#ifndef WBST_TESTER
#define WBST_TESTER

#include "wbst_headers.h"
#include "question.h"
#include "singletest.h"
#include <boost/thread/mutex.hpp>


namespace wbst
{
	typedef boost::shared_ptr<boost::thread> ThreadPtr;

	struct Triple
	{
		Triple(int m, int c, int t)	: matrix_no(m), cmp_no(c), test_no(t)
		{}

		bool operator <(const Triple &t) const;
		int matrix_no;
		int cmp_no;
		int test_no;
	};

	struct ThreadData
	{
		ThreadData(Triple t, ThreadPtr th, SingleTestThreadPtr  stt)
			: triple(t), thread(th), test(stt)
		{}

		Triple triple;
		ThreadPtr thread;
		SingleTestThreadPtr test;

	};
	typedef boost::shared_ptr<ThreadData> ThreadDataPtr;

	class WBSTTester
	{
		public:
			WBSTTester(int ac, char*av[]);
			void Start();
		private:
			smartcomparator::compare::CompareFunctionPtr BuildFunction( const std::string& function, Matrices::SuperMatrixPtr);
			typedef std::map<int, ThreadDataPtr> Threads;
			void WaitForSomeThreadToFinish(Threads &threads);
			void WaitForAllThreads(Threads &threads);
			void WriteResults();
			void PrintString(const std::string & str);

			std::vector<std::string> m_vFunctions;
			std::vector< std::pair<std::string, std::string> > m_vPathToMatrix;
			std::vector<std::vector<WBSTQuestion> > m_vQuestions;
			std::vector<std::string> m_vWBSTFiles;
			std::map<Triple, SingleTestResult> m_mResults;
			size_t m_cThreads;
			int m_iLogInterval;
			std::string m_sOutDir;
			std::string m_sFlexClass;
			bool m_bLoadCCS;
			boost::mutex io_mutex;

	};
}//namespace wbst
#endif //WBST_TESTER
