/*
    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_SINGLETEST
#define WBST_SINGLETEST
#include "wbst_headers.h"
#include "question.h"

#include "boost/date_time/posix_time/posix_time.hpp"
#include <boost/thread/mutex.hpp>

namespace wbst
{
	struct SingleTestResult
	{
		SingleTestResult();
		size_t good;
		size_t bad;
		size_t skipped;
	};

	std::ostream & operator << (std::ostream&, const SingleTestResult &);

	class SingleTestThread
	{
		public:
			SingleTestThread( Matrices::SuperMatrixPtr pMatrix, std::vector<WBSTQuestion> questions, 
					smartcomparator::compare::CompareFunctionPtr pCmp, std::string &logfile, int thread_no,
					const std::string &flex_class, int loginterval, boost::mutex &iomutex);

			void operator() ();

			SingleTestResult GetAggregatedResults();

			bool IsRunning();

		private:
			void WriteResults();
			void SingleQuestion(size_t question_no);
			void PrintProgress(size_t question_no);
			void PrintString(const std::string & str);

			bool m_bIsRunning;
			Matrices::SuperMatrixPtr m_pMatrix;
			std::vector<WBSTQuestion> m_vQuestions;
			smartcomparator::compare::CompareFunctionPtr m_pCmp;
			std::string m_sLogFile;
			std::string m_sFlexClass;
			int m_iThreadNo;
			int m_iLogInterval;

			std::set<size_t> m_vGoodIndices;
			std::map<size_t, std::string> m_mBadToChoosen;
			std::set<size_t> m_vSkippedIndices;

			boost::posix_time::ptime m_StartTime;
			boost::posix_time::time_duration m_Duration;
			boost::mutex &io_mutex;
	};

	typedef boost::shared_ptr<SingleTestThread> SingleTestThreadPtr;
}//namespace wbst

#endif //WBST_SINGLETEST

