/*
    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.
*/

#include "matrices_all.h"
#include "comparator_all.h"
#include "old_wbst/singletest.h"
#include <mpi.h>
#include "old_wbst/options.h"
#include "../mpi_handler/mpi_handler.h"

namespace parallel
{
	namespace WBST
	{

		const int EXIT_CODE=-15000;
		const int GIVE_ME_TEST=-15001;
		const int READY_TO_WRITE=-15002;
		const int ALL_OK=-15003;


		/**
 * Function for master node. Divides tasks for nodes and saves their results into short CSV file.
 * \param matrices Vectors with paths to matrices
 * \param wbstTests Vector with paths to WBST test files
 * \param functions Function strings with parameters for FunctionFactory
 * \param resultsDir Path to results
 * \param testsTable Table translating number of test to matrix, WBST test and function
 * \param noLoop Information, whether tests should be done 1 to 1, or in a bruteforce manner
 * \param stat MPI_Status for communication
 */

		/**
 * Function for slave node. Receives tasks, computes, sends short report, saves current test, loops.
 * \param matrices Vectors with paths to matrices
 * \param wbstTests Vector with paths to WBST test files
 * \param functions Function strings with parameters for FunctionFactory
 * \param flexClass Flex class to find words, if flex class is not provided in WBST tests
 * \param resultsDir Path to results
 * \param testsTable Table translating number of test to matrix, WBST test and function
 * \param ccs Whether matrices should be loaded using ccs file
 * \param noXML Whether slave nodes should save results of each test to .txt file in XML format
 * \param stat MPI_Status for communication
 */


		class WBSTMaster
		{
		public:
			WBSTMaster();
			~WBSTMaster();
			void Init(WBSTOptions options,MPI_Status status);
			void Start();
			void Finalize();
		private:
			void createLogIndex();
			void printETA();
			void loadTestsTable(bool noLoop);
			void receivedGiveWorkMsg(int sourceNode);
			void receivingResults(int sourceNode);
			int numOfNodes;
			int totalNumberOfTests;
			std::vector< std::pair<std::string, std::string> > matrices;
			std::vector<std::string> wbstTests;
			std::vector<std::string> functions;
			int **testsTable;
			int**endResults;
			int testsDone;
			MPI_Status stat;
			std::ofstream output;
			int testsIterator;
			bool sortResults;
			std::ofstream reportFile;
			double startTime;
			MPI_Handler mpiHandler;
			std::string resultsDir;
			boost::posix_time::ptime start;
			boost::posix_time::time_duration total_time;


		};


		class WBSTSlave
		{
		public:
			WBSTSlave();
			void Init(WBSTOptions options,MPI_Status status);
			void Start();
			~WBSTSlave();
		private:
			void loadTestsTable(bool noLoop);
			void loadCompareFunction();
			void sendResults(SingleTestResult results);
			std::string getLogFileName();
			void fetchWork(bool &exitFlag);
			std::vector<WBSTQuestion> loadWBSTFile(std::string filename);

			std::vector< std::pair<std::string, std::string> > matrices;
			std::vector<std::string> wbstTests;
			std::vector<std::string> functions;
			std::string flexClass;
			std::string resultsDir;
			int **testsTable;
			bool ccs;
			bool noXML;
			MPI_Status stat;
			int myRank;
			int totalNumberOfTests;
			MPI_Handler mpiHandler;
			int oldMatrixNo;
			int oldFunctionNo;
			int matrixNo;
			int functionNo;
			int testNo;
			int currentRow;
			Matrices::SuperMatrixPtr pMatrix;
			smartcomparator::compare::CompareFunctionPtr pCmp;

		};
		/**
 * Function initializing parallel computing
 * \param matrices Vectors with paths to matrices
 * \param wbstTests Vector with paths to WBST test files
 * \param functions Function strings with parameters for FunctionFactory
 * \param flexClass Flex class to find words, if flex class is not provided in WBST tests
 * \param resultsDir Path to results
 * \param ccs Whether matrices should be loaded using ccs file
 * \param noLoop Information, whether tests should be done 1 to 1, or in a bruteforce manner
 * \param noXML Whether slave nodes should save results of each test to .txt file in XML format
 * \param ac Input argument count
 * \param av Input arguments
 */
		void runParallelWBST(WBSTOptions options,int ac, char **av);
	}
}
