/*File Name: save_store.cpp
  Author: Betti Oesterholz ; Date: 27.10.2007
  System: C++

  call: tSaveStore M T

  Description: This is the Tascase to check if the load and store-methods of the 
   objects work correct. 
   The test consists of creating a univers with the maximal points parameter set
   to M parameter. Then the univers(1) is stored to a file (univers 2 is in the 
   file), the univers is restored in a new object(univers 3) and stored again
   in asecound file(univers 4).
   In the the universes 1 and 3 are compared and the first und secound file.
   If all is equal the test has run successfully, else an error ist reported. 
   This is repeated till the test has run vor more then T secounds, if T is
   0 or not given the test runs forever.
  
  What's tested: - load( readUnivers()) and store( printUnivers()) methods of
     the univers
   - equal methods of the univers


  Copyright (C) 2007  Betti Oesterholz

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, June 1991, 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
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  History:

*/ 

#include <time.h>
#include <sys/stat.h>
#include <cstdlib>
#include <cstdio>

#include "cRandomMersenne.h"
#include "cUnivers.h"
#include "cUniversNeib.h"



#define  TEST_DATA_FOLDER "dataSaveStore/"

using namespace std;


int main(int argc,char* argv[])
{
	int iReturn=0;//returnvalue of the test; the number of occured Errors
	time_t tStartTime=time(0);//time of teststart
	time_t tMaxTestDuration=0;//duration this testrun should at minimum last( if 0 forever)
	long lMaxUniversPoints=10000;//maximal point the generated universums should have
	cRandomMersenne randGenerator(time(0));
	unsigned long ulActualIteration=0;
	
	//create the folder for the testdata
	mkdir(TEST_DATA_FOLDER, 0777);
//	mkdir(TEST_DATA_FOLDER, mode_t mode);
	
	if ( argc >= 2 )
	{//one parameter given; get parameter max univers points
		lMaxUniversPoints = atol(argv[1]);
		if ( lMaxUniversPoints < 1 )
			lMaxUniversPoints = 10000;
	}
	
	if ( argc >= 3 )
	{//two parameter given; read parameter max testrun duration time
		tMaxTestDuration = atol(argv[2]);
		if ( tMaxTestDuration < 0 )
			tMaxTestDuration = 0;
	}	
	
	cout<<endl<<"Running Test for save and store operations: tSaveStore"<<endl;
	cout<<      "======================================================"<<endl;
	cout<<"With maximal universpoints "<<lMaxUniversPoints;
	if (tMaxTestDuration)
	{
		cout<<" and a test duration of "<<tMaxTestDuration<<" secounds"<<endl<<endl;
	}else{
		cout<<" infinity"<<endl<<endl;
	}
	
	while ( (tMaxTestDuration==0) || (tStartTime + tMaxTestDuration > time(0) ) )
	{
		ulActualIteration++;
		cout<<endl<<"Starting Iteration "<<ulActualIteration<<endl;
		int iReturnAtIterationStart=iReturn;
		
		long lMaxUniversPointsForTest = randGenerator.IRandom( 1 , lMaxUniversPoints );// the maximal universum point for the actual test

		cUniversNeib universTest("save_store_parameter.txt");
		
		universTest.setMaxNumberOfPoints(lMaxUniversPointsForTest);
		
		cout<<"1. Creating univers"<<endl;
		universTest.start();//create the univers
		
		//store univers	
		char szUnivFileName1[1000];
		sprintf(szUnivFileName1,"%s%s%ld.1.txt",TEST_DATA_FOLDER,"univ",ulActualIteration);
		cout<<"2. Saving univers to "<<szUnivFileName1<<endl;
		
		ofstream osUniversFile(szUnivFileName1);
		if(osUniversFile)
		{
			universTest.printUnivers(osUniversFile);
			osUniversFile.close();
		}else{
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<< "Problem opening the univers file : "<<szUnivFileName1<<endl ;
			iReturn++;
		}
		
		//load to new univers
		cout<<"3. Loading univers from "<<szUnivFileName1<<endl;
		cUniversNeib universTestLoaded("save_store_parameter.txt");
		
		ifstream isUniversFile(szUnivFileName1);
		if(isUniversFile)
		{
			universTestLoaded.readUnivers(isUniversFile);
			isUniversFile.close();
		}else{
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<< "Problem opening the univers file : "<<szUnivFileName1<<endl ;
			iReturn++;
		}
		
		//store new univers
		char szUnivFileName2[1000];
		sprintf(szUnivFileName2,"%s%s%ld.2.txt",TEST_DATA_FOLDER,"univ",ulActualIteration);
		cout<<"4. Saving Univers to "<<szUnivFileName2<<endl;
		
		ofstream osUniversFile2(szUnivFileName2);
		if(osUniversFile2)
		{
			universTestLoaded.printUnivers(osUniversFile2);
			osUniversFile2.close();
		}else{
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<< "Problem opening the univers file : "<<szUnivFileName2<<endl ;
			iReturn++;
		}
		
		//compare universes
		cout<<"5. Comparing the two universes ";
		if ( universTestLoaded == universTest )
		{//universes are equal; all is OK
			cout<<"OK"<<endl;
		}else{//universes are not equal -> ERROR
			cout<<"Error"<<endl;
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<<"The two Universes are not equal "<<endl ;
			iReturn++;
		}
		
		//compare stored universes
		cout<<"6. Comparing the two stored universes "<<szUnivFileName1<<" and "<<szUnivFileName2<<endl;
		char szSystemCompareCall[1000];
		int iDiffResult=0;
		sprintf(szSystemCompareCall,"diff -q %s %s ;echo $? > diffResult.txt",szUnivFileName1,szUnivFileName2);
		system(szSystemCompareCall);
		
		ifstream isDiffResultFile("diffResult.txt");
		if(isDiffResultFile)
		{
			isDiffResultFile>>iDiffResult;
			osUniversFile2.close();
		}else{
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<<"Problem opening the diff result file : diffResult.txt"<<endl ;
			iReturn++;
		}
		
		if ( iDiffResult==0 )
		{//files are equal
			cout<<"OK: the files are equal"<<endl;
		}else{//files are not equal->error
			cerr<<"Error in Iteration "<<ulActualIteration<<" : ";
			cerr<<"the two stored universfiles are not equal"<<endl ;
			iReturn++;
		}
		
		//clean data if no Error has ocuored
		if ( iReturnAtIterationStart==iReturn )
		{//no Error in this iteration -> clean
			cout<<"Iteration with no Error. (Removing universfiles)"<<endl;
			remove(szUnivFileName1);
			remove(szUnivFileName2);
			remove("diffResult.txt");
		}
		
		
	}

	if ( iReturn==0 )
	{
		cout<<endl<<endl<<"Test successfull: no errors occoured"<<endl;
	}else{
		cerr<<endl<<endl<<"Test failed: "<<iReturn<<" errors occoured"<<endl;
	}

	return iReturn;
}













































