
#include "ANSODTraininingEngine.h"
#include "ANSYOLOTrainingEngine.h"
#include "ANSYOLOCLTrainingEngine.h"
#include "ANSYOLOSEGTrainingEngine.h"
#include "ANSTrainingEngine.h"
#include <fstream>
#include <sstream>
#include <string>
std::string readFileContent(const std::string& filePath) {
	std::ifstream fileStream(filePath);
	if (fileStream.is_open()) {
		std::string content((std::istreambuf_iterator<char>(fileStream)),
			std::istreambuf_iterator<char>());
		return content;
	}

}
int TestANSODTRE() {// For Older ODHUB version
	ANSCENTER::ANSODTRE ansEngine;
	std::string projectDirectory = "C:\\ProgramData\\Sh7O7nUe7vJ";
	std::string engineFolderDir = "C:\\ProgramData\\ANSCENTER\\Shared";
	std::string modelTemplateDir = "C:\\ProgramData\\ANSCENTER\\Shared";
	bool initResult = ansEngine.Init("", projectDirectory, engineFolderDir, modelTemplateDir, "",true);
	std::cout << "Init Result" << initResult << std::endl;
	std::vector<std::string> projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	// Set the working directory
	bool setWorkingDirectory = ansEngine.SetWorkingDirectory("C:\\Programs\\AITraining\\LPDetection");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;


	//1. Create a project
	bool createdProject = ansEngine.CreateProject("LicensePlate");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	//2. Browse to the working directory

	projectDirectory = ansEngine.GetProjectDirectory();
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	bool dataUploaded = ansEngine.UploadTrainingData("LicensePlate");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//3. Create a training engine

	bool createEngine = ansEngine.CreateTrainingEngine("LicensePlate", 1, 0, 2000, 32, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus = ansEngine.GetProjectExperimentStatus("LicensePlate", 1);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand = ansEngine.GenerateTrainingCommand("LicensePlate", 1, 0);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//4. Evaluate the model
	std::string evaluateModelCommand = ansEngine.EvaluateModel("LicensePlate", 1);
	std::cout << "Evaluation Result:" << evaluateModelCommand << std::endl;

	//5. Download the model
	std::string saveModelPath = "C:\\Programs\\AITraining\\LPDetection\\Models";
	ansEngine.DownloadModel("LicensePlate", 1, saveModelPath);
	return 0;
}
int TestANSYLTRE() {// For New Yolo version
	ANSCENTER::ANYLTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "";
	bool initResult = ansEngine.Init("", projectDirectory, engineFolderDir, modelTemplateDir, "",true);
	std::cout << "Init Result" << initResult << std::endl;
	std::vector<std::string> projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	//// Set the working directory
	bool setWorkingDirectory = ansEngine.SetWorkingDirectory("C:\\Programs\\TrainingToolTest\\CocoTest");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;


	////1. Create a project
	bool createdProject = ansEngine.CreateProject("CocoTest");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	projectDirectory = ansEngine.GetProjectDirectory();
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	bool dataUploaded = ansEngine.UploadTrainingData("CocoTest");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine

	bool createEngine = ansEngine.CreateTrainingEngine("CocoTest", 1, 0, 2000, 32, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus = ansEngine.GetProjectExperimentStatus("CocoTest", 1);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand = ansEngine.GenerateTrainingCommand("CocoTest", 1, 0);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string evaluateModelCommand = ansEngine.EvaluateModel("CocoTest", 1);
	std::cout << "Evaluation Result:" << evaluateModelCommand << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\TrainingToolTest\\CocoTest\\Models";
	ansEngine.DownloadModel("CocoTest", 1, saveModelPath, 0);
	ansEngine.DownloadModel("CocoTest", 1, saveModelPath, 1);

	return 0;
}
int TestANSYLCLTRE() {// For Classfication
	ANSCENTER::ANYLCLTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "";
	bool initResult = ansEngine.Init("", projectDirectory, engineFolderDir, modelTemplateDir, "", true);
	std::cout << "Init Result" << initResult << std::endl;
	std::vector<std::string> projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	//// Set the working directory
	bool setWorkingDirectory = ansEngine.SetWorkingDirectory("C:\\Programs\\TrainingToolTest\\Classification\\FMTest");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;


	////1. Create a project
	bool createdProject = ansEngine.CreateProject("FireNSmokeClassifier");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	//projectDirectory = ansEngine.GetProjectDirectory();
	//std::cout << "Project Directory:" << projectDirectory << std::endl;

	//bool dataUploaded = ansEngine.UploadTrainingData("FMTest");
	//if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine

	bool createEngine = ansEngine.CreateTrainingEngine("FireNSmokeClassifier", 1, 0, 2000, 32, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus = ansEngine.GetProjectExperimentStatus("FireNSmokeClassifier", 1);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand = ansEngine.GenerateTrainingCommand("FireNSmokeClassifier", 1, 0);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string evaluateModelCommand = ansEngine.EvaluateModel("FireNSmokeClassifier", 1);
	std::cout << "Evaluation Result:" << evaluateModelCommand << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\TrainingToolTest\\Classification\\FMTest\\Models";
	//ansEngine.DownloadModel("FireNSmokeClassifier", 1, saveModelPath, 0);
	ansEngine.DownloadModel("FireNSmokeClassifier", 1, saveModelPath, 1);

	return 0;
}

int TestANSTRE() {// 
	ANSCENTER::ANYLTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "";
	ANSCENTER::ANSTRE* infHandle;
	int trainingEngineType = 1;
	// Create the handle
	bool initResult = CreateANSTREHandle(&infHandle, "", projectDirectory.c_str(), engineFolderDir.c_str(), modelTemplateDir.c_str(), "", trainingEngineType,true);
	std::cout << "Init Result" << initResult << std::endl;

	std::string strProjects;
	ANSTRE_GetProjects_CPP(&infHandle, strProjects);
	std::cout << "Projects:" << strProjects << std::endl;


	//// Set the working directory
	bool setWorkingDirectory=ANSTRE_SetWorkingDirectory(&infHandle, "C:\\Programs\\AITraining\\LPDetection");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;
	
	////1. Create a project
	bool createdProject =ANSTRE_CreateProject(&infHandle, "LicensePlate");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	ANSTRE_GetProjectDirectory_CPP(&infHandle, projectDirectory);
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	std::string trainingResultFile ="C:\\Projects\\ANLS\\Documents\\trainingResults.txt";
	std::string trainingResuls= readFileContent(trainingResultFile);
	std::string parsedResults;
	ANSTRE_ParseTrainingResults_CPP(&infHandle, trainingResuls.c_str(), parsedResults);
	std::cout << "Parsed Results:" << parsedResults << std::endl;


	bool dataUploaded = ANSTRE_UploadTrainingData(&infHandle, "LicensePlate");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine
	bool createEngine = ANSTRE_CreateTrainingEngine(&infHandle, "LicensePlate", 1, 0, 2000, 32, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus;
	ANSTRE_GetProjectExperimentStatus_CPP(&infHandle, "LicensePlate", 1, projectExperimentStatus);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand;
	ANSTRE_GenerateTrainingCommand_CPP(&infHandle, "LicensePlate", 1, 0, trainingCommand);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string mAPResult;
	ANSTRE_EvaluateModel_CPP(&infHandle, "LicensePlate", 1, mAPResult);
	std::cout << "Evaluation Result:" << mAPResult << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\AITraining\\LPDetection\\Models";
	ANSTRE_DownloadModel(&infHandle, "LicensePlate", 1, saveModelPath.c_str(), 0);
	if(trainingEngineType==1) ANSTRE_DownloadModel(&infHandle, "LicensePlate", 1, saveModelPath.c_str(), 1);

	return 0;
}
int FaceMaskDetection() {// 
	ANSCENTER::ANYLTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "C:\\Program Files\\ANSCENTER\\ANS Object Detection\\data";
	ANSCENTER::ANSTRE* infHandle;
	int trainingEngineType = 0;
	// Create the handle
	bool initResult = CreateANSTREHandle(&infHandle, "", projectDirectory.c_str(), engineFolderDir.c_str(), modelTemplateDir.c_str(), "", trainingEngineType,true);
	std::cout << "Init Result" << initResult << std::endl;

	std::string strProjects;
	ANSTRE_GetProjects_CPP(&infHandle, strProjects);
	std::cout << "Projects:" << strProjects << std::endl;


	//// Set the working directory
	bool setWorkingDirectory = ANSTRE_SetWorkingDirectory(&infHandle, "C:\\Programs\\AITraining\\Mask");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;

	////1. Create a project
	bool createdProject = ANSTRE_CreateProject(&infHandle, "Face Mask 5");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	ANSTRE_GetProjectDirectory_CPP(&infHandle, projectDirectory);
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	bool dataUploaded = ANSTRE_UploadTrainingData(&infHandle, "Face Mask 5");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine
	bool createEngine = ANSTRE_CreateTrainingEngine (& infHandle, "Face Mask 5", 1, 3, 2000, 1, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus;
	ANSTRE_GetProjectExperimentStatus_CPP(&infHandle, "Face Mask 5", 1, projectExperimentStatus);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand;
	ANSTRE_GenerateTrainingCommand_CPP(& infHandle, "Face Mask 5", 1, 3, trainingCommand);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string mAPResult;
	ANSTRE_EvaluateModel_CPP(&infHandle, "Face_Mask_3", 1, mAPResult);
	std::cout << "Evaluation Result:" << mAPResult << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\AITraining\\Mask\\Models";
	ANSTRE_DownloadModel(&infHandle, "LicensePlate", 1, saveModelPath.c_str(), 0);
	if (trainingEngineType == 1) ANSTRE_DownloadModel(&infHandle, "Face Mask 5", 1, saveModelPath.c_str(), 1);
	return 0;
}
int FallDetection() {
	ANSCENTER::ANYLTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "";
	ANSCENTER::ANSTRE* infHandle;
	int trainingEngineType = 0; // Using the Yolov8
	// Create the handle
	bool initResult = CreateANSTREHandle(&infHandle, "", projectDirectory.c_str(), engineFolderDir.c_str(), modelTemplateDir.c_str(), "", trainingEngineType,false);
	std::cout << "Init Result" << initResult << std::endl;


	int engineInstalled= ANSTRE_CheckEngine(&infHandle);
	std::cout << "Engine Installed:" << engineInstalled << std::endl;
	std::string strProjects;
	ANSTRE_GetProjects_CPP(&infHandle, strProjects);
	std::cout << "Projects:" << strProjects << std::endl;

	//// Set the working directory
	bool setWorkingDirectory = ANSTRE_SetWorkingDirectory(&infHandle, "C:\\Programs\\TrainingWorkingStation\\Projects\\FallDetection");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;

	////1. Create a project
	bool createdProject = ANSTRE_CreateProject(&infHandle, "Fall Detection");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	ANSTRE_GetProjectDirectory_CPP(&infHandle, projectDirectory);
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	bool dataUploaded = ANSTRE_UploadTrainingData(&infHandle, "Fall Detection");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine
	bool createEngine = ANSTRE_CreateTrainingEngine(&infHandle, "Fall Detection", 1, 3, 2000, 1, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus;
	ANSTRE_GetProjectExperimentStatus_CPP(&infHandle, "Fall Detection", 1, projectExperimentStatus);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand;
	ANSTRE_GenerateTrainingCommand_CPP(&infHandle, "Fall Detection", 1, 3, trainingCommand);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string mAPResult;
	ANSTRE_EvaluateModel_CPP(&infHandle, "Fall Detection", 1, mAPResult);
	std::cout << "Evaluation Result:" << mAPResult << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\TrainingWorkingStation\\Projects\\FallDetection\\Models";
	ANSTRE_DownloadModel(&infHandle, "FallDetection", 1, saveModelPath.c_str(), 0);
	if (trainingEngineType == 1) ANSTRE_DownloadModel(&infHandle, "Fall Detection", 1, saveModelPath.c_str(), 1);

	return 0;
}

// Segmentaion
int TestSegmentationEngine() {// For New Yolo version
	ANSCENTER::ANYLSEGTRE ansEngine;
	std::string projectDirectory = "";
	std::string engineFolderDir = "";
	std::string modelTemplateDir = "";
	bool initResult = ansEngine.Init("", projectDirectory, engineFolderDir, modelTemplateDir, "", true);
	std::cout << "Init Result" << initResult << std::endl;
	std::vector<std::string> projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	projects = ansEngine.GetProjects();
	if (projects.size() > 0) {
		for (int i = 0; i < projects.size(); i++) {
			std::cout << "Project Name:" << projects[i] << std::endl;
			std::vector<std::string> experiments = ansEngine.GetProjectExperiments(projects[i]);
			if (experiments.size() > 0) {
				for (int i = 0; i < experiments.size(); i++) {
					std::cout << "-- Project Experiment:" << experiments[i] << std::endl;
				}
			}
		}
	}

	//// Set the working directory
	bool setWorkingDirectory = ansEngine.SetWorkingDirectory("C:\\Programs\\TrainingToolTest\\SegmentationEngine\\SegmeTxtYolo");
	if (!setWorkingDirectory)std::cout << "Working Directory Not Set" << std::endl;


	////1. Create a project
	bool createdProject = ansEngine.CreateProject("SegmentationTest");
	if (!createdProject)std::cout << "Project Not Created" << std::endl;

	////2. Browse to the working directory
	projectDirectory = ansEngine.GetProjectDirectory();
	std::cout << "Project Directory:" << projectDirectory << std::endl;

	bool dataUploaded = ansEngine.UploadTrainingData("SegmentationTest");
	if (!dataUploaded)std::cout << "Cannot upload data" << std::endl;

	//////3. Create a training engine

	bool createEngine = ansEngine.CreateTrainingEngine("SegmentationTest", 1, 0, 2000, 32, 0.001);
	if (!createEngine)std::cout << "Cannot create engine" << std::endl;

	std::string projectExperimentStatus = ansEngine.GetProjectExperimentStatus("SegmentationTest", 1);
	std::cout << projectExperimentStatus << std::endl;

	std::string trainingCommand = ansEngine.GenerateTrainingCommand("SegmentationTest", 1, 0);
	std::cout << "Training Command:" << trainingCommand << std::endl;

	//// 4. Evaluate the model
	std::string evaluateModelCommand = ansEngine.EvaluateModel("SegmentationTest", 1);
	std::cout << "Evaluation Result:" << evaluateModelCommand << std::endl;

	//// 5. Download the model
	std::string saveModelPath = "C:\\Programs\\TrainingToolTest\\SegmentationEngine\\SegmeTxtYolo\\Models";
	ansEngine.DownloadModel("SegmentationTest", 1, saveModelPath, 0);
	ansEngine.DownloadModel("SegmentationTest", 1, saveModelPath, 1);

	return 0;
}

int main()
{
	TestSegmentationEngine();	
	//TestANSYLTRE();
	//TestANSYLCLTRE();
	//FallDetection();
	//TestANSTRE();
	//FaceMaskDetection();
	//TestANSTRE();
	//TestANSODTRE();
	//TestANSYLTRE();
	return 0;
}