/*
    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 "tester.h"


//Wybrane testy:
//
//0 - wbst=/home2/mpiasecki/dane/wbst/noun/hwbst/nowe/folds/hwbst_2008-10-09_tf500_teach.csv
//1 - wbst=/home2/mpiasecki/dane/wbst/noun/hwbst/nowe/folds/hwbst_2008-10-09_tf500_test.csv

//Funkcje:

//0 - sim=rwf_lin(rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)
//1 - sim=rwf_lin(rank_size=10000, uniform_rank = false)

//2 - sim=rwf_pmi(discount=true,rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)
//3 - sim=rwf_pmi(discount=true,rank_size=10000, uniform_rank = false)

//4 - sim=rwf_zscore(rz=5, rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)
//5 - sim=rwf_zscore(rz=5, rank_size=10000, uniform_rank = false)

//6 - sim=lin()
//7 - sim=pmi(discount=true)
//8 - sim=crm_dmi()

std::string functions[numOfFunctions]={"rwf_lin(rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)",
					   "rwf_lin(rank_size=10000, uniform_rank = false)",
					   "rwf_pmi(discount=true,rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)",
					   "rwf_pmi(discount=true,rank_size=10000, uniform_rank = false)",
					   "rwf_zscore(rz=5, rank_size=10000, uniform_rank = false, partial_order=true, div_factor=1, sports_order=true)",
					   "rwf_zscore(rz=5, rank_size=10000, uniform_rank = false)",
					   "lin()",
					   "pmi(discount=true)",
					   "crm_dmi()"};

std::string testFiles[numOfTests]={"/home2/mpiasecki/dane/wbst/noun/hwbst/nowe/folds/hwbst_2008-10-09_tf500_teach.csv",
				   "/home2/mpiasecki/dane/wbst/noun/hwbst/nowe/folds/hwbst_2008-10-09_tf500_test.csv"};

double previousResults[numOfFunctions][numOfTests]={{0.856942,0.859073},		//0
							{0.858698,0.862934},		//1
							{0.822714,0.825377},		//2
							{0.826575,0.829589},		//3
							{0.839214,0.844507},		//4
							{0.838863,0.845384},		//5
							{0.839916,0.845033},		//6
							{0.803054,0.801509},		//7
							{0.827453,0.832573}};		//8



WBSTTester::WBSTTester()
{

}
WBSTTester::~WBSTTester()
{

}
void WBSTTester::Init()
{

}
boost::filesystem::path WBSTTester::prepareConfigFile()
{
	Config *cfg = Config::getInstance();
	boost::filesystem::path configPath(cfg->workdir);
	configPath/="config.cfg";
	std::ofstream configFile(configPath.string().c_str());
	if(!configFile)
		throw std::runtime_error("Cannot open config file!\n");
	for(size_t i = 0;i<cfg->matrices.size();i++)
		configFile<<"matrices="<<cfg->matrices[i]<<std::endl;
	for(size_t i=0;i<cfg->wbstTests.size();i++)
		configFile<<"wbst="<<cfg->wbstTests[i]<<std::endl;
	for(size_t i =0;i<cfg->functions.size();i++)
		configFile<<"sim="<<cfg->functions[i]<<std::endl;

	configFile<<"outdir="<<cfg->workdir<<std::endl;
	configFile<<"flex="<<cfg->flex<<std::endl;
	configFile<<"load-ccs="<<cfg->loadCCS<<std::endl;
	configFile.close();
	return configPath;
}
void WBSTTester::readResults()
{
	std::map<std::string,int> function2ID;
	std::map<std::string,int> test2ID;
	for(int i=0;i<numOfFunctions;i++)
		function2ID[functions[i]] = i;
	for(int i=0;i<numOfTests;i++)
	{
		boost::filesystem::path testPath(testFiles[i]);
		test2ID[std::string( testPath.filename().c_str() )] = i;
	}


	Config *cfg = Config::getInstance();
	boost::filesystem::path resultsPath(cfg->workdir);
	resultsPath/="results.csv";
	std::ifstream resultsFile(resultsPath.string().c_str());
	std::string line;
	//First line is just a header
	std::getline(resultsFile,line);
	std::vector<std::string> tokens;
	for(size_t i=0;i<cfg->wbstTests.size()*cfg->functions.size()*cfg->matrices.size();i++)

	{
		std::getline(resultsFile,line);
		boost::split(tokens,line,boost::is_any_of(";"));
		if(tokens.size()!=9)
			throw std::runtime_error("Error in results file");
		std::string sim = tokens[2];
		std::string test = tokens[4];
		results[function2ID[sim]][test2ID[test]] = atof(tokens[8].c_str());
		//Test
		//		std::cout<<"Read sim: "<<" - "<<function2ID[sim]<<", test: "<<test<<" - "<<test2ID[test]
		//				<<", result: "<<results[function2ID[sim]][test2ID[test]]<<std::endl;

	}
}

void WBSTTester::printResults()
{
	std::cout<<"\told_result\tnew_result\tdifference\tFunction\n";
	for(int i=0;i<numOfTests;i++)
	{
		std::cout<<"Test: "<<testFiles[i]<<std::endl;
		for(int j=0;j<numOfFunctions;j++)
		{
			std::cout<<"\t"<<previousResults[j][i]<<"\t"<<results[j][i]<<"\t"
					<<fabs(previousResults[j][i]-results[j][i])<<"\t"<<functions[j]<<std::endl;
			if(fabs(previousResults[j][i]-results[j][i])>0.01)
				std::cerr<<"Difference greater than 1%!\n";
		}
	}
}


void WBSTTester::Start()
{
	Config *cfg = Config::getInstance();
	boost::filesystem::path configPath = prepareConfigFile();

	std::stringstream ss;
	ss<<"mpirun -n "<<cfg->numOfNodes<<" --hostfile "<<cfg->hostFile<<" "<<cfg->wbstTesterPath<<" --config-file "<<configPath.string();
	int returnValue = system(ss.str().c_str());
	if(returnValue !=0)
		std::cerr<<"Return value from system: "<<returnValue<<std::endl;
	readResults();
	printResults();




}
