// Copyright (c) 2024 Orange. All rights reserved.
// This software is distributed under the BSD 3-Clause-clear License, the text of which is available
// at https://spdx.org/licenses/BSD-3-Clause-Clear.html or see the "LICENSE" file for more details.

#include "Test.h"

void Test(int argc, char** argv)
{
	// ALString sPath = "c:\\users\\boullema\\learning.v4\\KWTest\\TestData\\";

	// TestOpenManyFiles();
	// mainReplaceBlanksByTabs(argc, argv);
	// KWTextParser::TextParserTest(argc, argv);
	// KWSNBStudy::Test();
	// KWDataGridTest::TestNonAsymptotic();
	// KWCoclustering::CoclusteringTest(argc, argv);
	// KWDataGridTest::DataGridTest(argc, argv);
	// KWDataGridTest::Test();
	// KWDataGrid::Test();
	// KWDensityEstimationStudy::Test();
	// KWPredictorSpecArrayView::Test();
	// KWPredictorSpecView::Test();
	// KWStatisticalEvaluation::Test();
	// KWGrouperTest::TestAll();
	// KWGrouperTest::TestHiddenGroupSamples();
	// KWDiscretizerMODL::TestGranularizeFrequencyTable();
	// KWGrouperMODL::TestGranularizeFrequencyTable();
	// KWDiscretizerTest::TestLinearProbSamples();
	// KWDiscretizerTest::TestSinusSignSamples();
	// KWDiscretizerTest::TestRandomSamples();
	// KWDiscretizerTest::TestRandomSamplesForPriorV9();
	// KWDiscretizerTest::TestNewPriorThreshold();
	// KWDiscretizerTest::TestAll();
	// Symbol::Test();
	// SymbolVector::Test();
	// MODLStudy3();
	// MachineLearningTest();
	// KWStat::Test();
	// KWSTDatabaseTextFile::TestReadWrite(sPath+"TestRules.kdic", "TestRules", sPath+"TestRules.txt",
	// sPath+"TestRulesOut.txt"); KWSTDatabaseTextFile::TestReadWrite("", "",
	// "e:\\learning\\bmgp\\apprentissage.txt", ""); KWSTDatabaseTextFile::TestReadWrite("", "",
	// "e:\\learning\\adult\\adult.txt", "c:\\temp\\adult.txt"); KWSTDatabaseTextFile::TestReadWrite("", "",
	// "e:\\learning\\adult\\adult.txt", "c:\\temp\\adult.txt"); KWSTDatabaseTextFile::Test(); KWObject::Test();
	// KWDerivationRule::Test();
	// KWValue::Test();
	// KWContinuous::Test();
	// Date::Test();
	// KWDateFormat::Test();
	// Time::Test();
	// KWTimeFormat::Test();
	// Timestamp::Test();
	// KWTimestampFormat::Test();
	// TimestampTZ::Test();
	// KWTimestampTZFormat::Test();
	// KWTypeAvailableFormats::Test();
	// KWTypeAutomaticRecognition::Test();
	// KWClass::Test();
	// KWClassDomain::Test();
	// KWClassDomain::TestReadWrite(AcquireString("Fichier de dictionnaire", ""),
	//     "c:\\temp\\UnloadTest.kdic");
	// if (argv == 3)
	// cout << FileService::GetFilePath("khiops.exe", "c:\\;c:\\tmp;e:\\learning;e:");
	// KWDataGridStats::Test();
	// KWProbabilityTable::Test();
	//
	// ComputeGraphModularity::Study(argc, argv);
	// ComputeGraphModularity::CreateRandomGraph(argc, argv);
	// ComputeGraphModularity::CreateCircularRandomGraph(argc, argv);
	// mainGenerateScaleFreeGraph(argc, argv);
	// mainGenerateCurves(argc, argv);
	// TranscodeDigitDataset();
	// ObjectKey::Test();
	// KDMultinomialSamplingStudy::Test();
	// KDMultinomialSampleGenerator::Test();
	// FileCache::TestCountLines("C:\\Users\\boullema\\LearningTest\\datasets\\Census\\Census.txt", false);
	// InputBufferedFile::Test();
	// InputBufferedFile::TestCountLines("C:\\Users\\boullema\\LearningTest\\datasets\\Census\\Census.txt");
	// OutputBufferedFile::TestWriteFile("C:\\Users\\boullema\\LearningTest\\datasets\\Census\\Census.txt",
	// "c:\\temp\\Census.txt"); KWMetaData::Test(); PEShared_StructuredObjectExample::Test();
	// PLShared_Boolean::Test();
	// PLShared_Double::Test();
	// PLShared_Int::Test();
	// PLShared_Longint::Test();
	// PLShared_String::Test();
	// PLShared_Char::Test();
	// PLShared_StringVector::Test();
	// PLShared_IntVector::Test();
	// PLShared_LongintVector::Test();
	// PLShared_DoubleVector::Test();
	// PLShared_CharVector::Test();
	// PLSharedVariable::Test();
	// PLShared_ObjectDictionary::Test();
	// PLShared_ObjectList::Test();
	// PLShared_ObjectArray::Test();
	// PLSerializer::Test();
	// KWArtificialDataset::Test();
	// KWSortBuckets::Test();
	// KWFileKeyExtractorTask::Test();
	// KWKeySizeEvaluatorTask::Test();
	// KWKeySampleExtractorTask::Test();
	// KWSortedChunkBuilderTask::Test();
	// KWChunkSorterTask::Test();
	// KWFileSorter::Test();
	// RMResourceManager::Test();
	// PEProtocolTestTask::Test();
	// KWTestDatabaseTransferTask::STMainTestReadWrite(argc, argv);
	// KWTestDatabaseTransferTask::STTest();
	// KWTestDatabaseTransferTask::MTMainTestReadWrite(argc, argv);
	// KWTestDatabaseTransferTask::MTTest();
	// KWKeyPositionSampleExtractorTask::Test();
	// KWKeyPositionFinderTask::Test();
	// KWQuantileIntervalBuilder::Test();
	// KWQuantileGroupBuilder::Test();
	// KWTupleTable::Test();
	// KWTupleTableLoader::Test();
	// KWHierarchicalMultinomialStudy::TestDataset();
	// PLShared_TupleTable::Test();
	// PLShared_DataGridStats::Test();
	// PLShared_DGSAttributeDiscretization::Test();
	// PLShared_DGSAttributeGrouping::Test();
	// PLShared_DGSAttributeContinuousValues::Test();
	// PLShared_DGSAttributeSymbolValues::Test();
	// JSONFile::Test();
	// KWIndexedCKeyBlock::Test();
	// KWIndexedNKeyBlock::Test();
	// KWContinuousValueBlock::TestPerformance();
	// KWContinuousValueBlockTest::TestPerformance();
	// IntPairVector::Test();
	// KWDataTableSliceSet::Test();
	// KWContinuousValueBlock::Test();
	// KWSymbolValueBlock::Test();
	// KWObjectArrayValueBlock::Test();
	// KWCDUniqueString::Test();
	// SNBIndexVector::Test();
	// KWTextService::Test();
	// KWTextNgramTokenizer::Test();
	// KWTextWordTokenizer::Test();
	// KWTextTokenizer::Test();
	KWResultFilePathBuilder::Test();
}

void KWTestAllComponents(boolean bLong)
{
	ALString sHeader = "=========================================================\n";

	// On passe en mode textuel
	UIObject::SetUIMode(UIObject::Textual);

	// On passe en mode batch pour avoir des parametres par defaut, sans interaction utilisateur
	SetAcquireBatchMode(true);

	// Lancement de tous les tests simples
	cout << sHeader << "Data grid\n";
	KWDataGrid::Test();
	cout << sHeader << "Symbol vector\n";
	SymbolVector::Test();
	cout << sHeader << "Symbol\n";
	Symbol::Test();
	cout << sHeader << "Stats\n";
	KWStat::Test();
	cout << sHeader << "Quantile interval builder\n";
	KWQuantileIntervalBuilder::Test();
	cout << sHeader << "Quantile group builder\n";
	KWQuantileGroupBuilder::Test();
	cout << sHeader << "Dictionary\n";
	KWClass::Test();
	cout << sHeader << "Dictionary domain\n";
	KWClassDomain::Test();
	cout << sHeader << "ST database text file\n";
	KWSTDatabaseTextFile::Test();
	cout << sHeader << "SYSTEM\tObject ([address] of object vary from run to run) \n";
	KWObject::Test();
	cout << sHeader << "Object key\n";
	KWObjectKey::Test();
	cout << sHeader << "Derivation rule\n";
	KWDerivationRule::Test();
	cout << sHeader << "Object values\n";
	KWValue::Test();
	cout << sHeader << "Continuous values\n";
	KWContinuous::Test();
	cout << sHeader << "Date values\n";
	Date::Test();
	cout << sHeader << "Date formats\n";
	KWDateFormat::Test();
	cout << sHeader << "Time values\n";
	Time::Test();
	cout << sHeader << "Time formats\n";
	KWTimeFormat::Test();
	cout << sHeader << "Timestamp values\n";
	Timestamp::Test();
	cout << sHeader << "Timestamp formats\n";
	KWTimestampFormat::Test();
	cout << sHeader << "Available formats\n";
	KWTypeAvailableFormats::Test();
	cout << sHeader << "Type Automatic Recognition\n";
	KWTypeAutomaticRecognition::Test();
	cout << sHeader << "DataGrid stats\n";
	KWDataGridStats::Test();
	cout << sHeader << "Probability table\n";
	KWProbabilityTable::Test();
	cout << sHeader << "Meta data\n";
	KWMetaData::Test();
	cout << sHeader << "Multinomial sampling study\n";
	KDMultinomialSamplingStudy::Test();
	cout << sHeader << "Multinomial sampling generator\n";
	KDMultinomialSampleGenerator::Test();
	cout << sHeader << "Load index\n";
	KWLoadIndex::Test();
	cout << sHeader << "Indexed key block\n";
	KWIndexedCKeyBlock::Test();
	cout << sHeader << "Sparse value block\n";
	KWValueBlock::Test();
	cout << sHeader << "Continuous value dictionary\n";
	KWContinuousValueDictionary::Test();
	cout << sHeader << "Continuous sparse value block\n";
	KWContinuousValueBlock::Test();
	cout << sHeader << "Symbol value dictionary\n";
	KWSymbolValueDictionary::Test();
	cout << sHeader << "Symbol sparse value block\n";
	KWSymbolValueBlock::Test();
	cout << sHeader << "ObjectArray value dictionary\n";
	KWObjectArrayValueDictionary::Test();
	cout << sHeader << "ObjectArray sparse value block\n";
	KWObjectArrayValueBlock::Test();
	cout << sHeader << "Tuple table\n";
	KWTupleTable::Test();
	cout << sHeader << "Tuple table loader\n";
	KWTupleTableLoader::Test();
	cout << sHeader << "Shared Symbol\n";
	PLShared_Symbol::Test();
	cout << sHeader << "Shared SymbolVector\n";
	PLShared_SymbolVector::Test();
	cout << sHeader << "Shared Continuous\n";
	PLShared_Continuous::Test();
	cout << sHeader << "Shared ContinuousVector\n";
	PLShared_ContinuousVector::Test();
	cout << sHeader << "Shared TupleTable\n";
	PLShared_TupleTable::Test();
	cout << sHeader << "Shared DataGridStats\n";
	PLShared_DataGridStats::Test();
	cout << sHeader << "Shared DGSAttributeDiscretization\n";
	PLShared_DGSAttributeDiscretization::Test();
	cout << sHeader << "Shared DGSAttributeGrouping\n";
	PLShared_DGSAttributeGrouping::Test();
	cout << sHeader << "Shared DGSAttributeContinuousValues\n";
	PLShared_DGSAttributeContinuousValues::Test();
	cout << sHeader << "Shared DGSAttributeSymbolValues\n";
	PLShared_DGSAttributeSymbolValues::Test();
	cout << sHeader << "Database transfer\n";
	KWTestDatabaseTransfer::Test();

	// Lancement de tous les tests longs
	if (bLong)
	{
		cout << sHeader << "Input buffered file\n";
		InputBufferedFile::Test(0);
	}
}

int main(int argc, char** argv)
{
	KWLearningProject learningProject;
	const ALString sBatchOption = "-batch";
	const ALString sBigBatchOption = "-bigbatch";
	boolean bBigBatch;

	// Parametrage de l'utilisation de MPI
	//DDD UseMPI();

	// Initialisation de l'environnement
	learningProject.Begin();

	// Creation du directory des fichiers temporaires
	FileService::CreateApplicationTmpDir();
	FileService::TouchApplicationTmpDir(1000);

	// Processus maitre
	if (PLParallelTask::IsMasterProcess())
	{
		// Parametrage de l'arret de l'allocateur
		// MemSetAllocIndexExit(8312);

		// Simulation du mode parallele pour le debuggage
		// PLParallelTask::SetParallelSimulated(true);
		// PLParallelTask::SetSimulatedSlaveNumber(10);

		// Passage en mode graphic
		// UIObject::ParseMainParameters(argc, argv);
		UIObject::SetUIMode(UIObject::Graphic);

		// Execution des tests en mode batch si option -batch ou -bigbatch sur la ligne de commande
		if (argc >= 2 and (sBatchOption == (const char*)argv[1] or sBigBatchOption == (const char*)argv[1]))
		{
			// Acces au flag de la version longue ou non des batch
			bBigBatch = (sBigBatchOption == (const char*)argv[1]);

			// Cas standard (avec cout)
			if (argc == 2)
				KWTestAllComponents(bBigBatch);
			// Cas avec nom de fichier de sortie sur la ligne de commande
			else
			{
				// Utilisation d'un stream dedie au batch
				ofstream batchCout(argv[2]);

				// Sauvegarde du buffer associe a cout
				streambuf* coutBuf = std::cout.rdbuf();

				// Redirection de cout vers le stream dedie a ubatch
				cout.rdbuf(batchCout.rdbuf());

				// Lancement des tests
				KWTestAllComponents(bBigBatch);

				// On restitue cout dans son etat initial
				cout.rdbuf(coutBuf);
			}
		}
		// Lancement des tests classiques
		else
		{
			// UIObject::ParseMainParameters(argc, argv);
			Test(argc, argv);
		}
	}

	// Fermeture de l'environnement
	learningProject.End();

	return 0;
}
