#ifndef ANSYLOBBTRE_H
#define ANSYLOBBTRE_H
#pragma once
#include "ANSTrainingEngine.h"
namespace ANSCENTER {
	class ANSTRE_API ANYLOBBTRE :public ANSTRE {
	public:
		ANYLOBBTRE();
		~ANYLOBBTRE();
		[[nodiscard]] bool Init(std::string licenseKey, std::string projectDirectory, std::string engineDirectory, std::string modelTemplateDirectory, std::string modelZipPassword, bool isLatestEngine)override;
		[[nodiscard]] std::vector<std::string> GetProjects()override;// Return a list of projects in the project directory
		[[nodiscard]] std::vector<std::string> GetProjectExperiments(std::string projectName)override;// Return a list of experiments for a specific project
		[[nodiscard]] bool CreateProject(std::string projectName)override;
		[[nodiscard]] bool DeleteProject(std::string projectName)override;
		[[nodiscard]] bool SetWorkingDirectory(std::string workingDirectory)override;
		[[nodiscard]] bool UploadTrainingData(std::string projectName)override;	// Upload the training data to the project
		[[nodiscard]] bool CreateTrainingEngine(std::string projectName, int experimentNumber, int extractorType, long numberStep, int batchSize, double learningRate)override;// extractorType =0: FAST, 1: ACCURATE; 2: VERY ACCURATE
		[[nodiscard]] std::string GetProjectExperimentStatus(std::string projectName, int experimentNumber)override;// Return the status of a specific experiment
		[[nodiscard]] std::string GenerateTrainingCommand(std::string projectName, int experimentNumber, int extractorType)override; //Generate the training command
		[[nodiscard]] std::string GenerateCustomTrainingCommand(std::string projectName, int experimentNumber, int extractorType, std::string pretrainedModel)override; //Generate the training command
		[[nodiscard]] std::string GenerateEvaluateModelCommand(std::string projectName, int experimentNumber, bool& zipModelExist)override;		   //Evaluate the accuracy of the model
		[[nodiscard]] std::string EvaluateModel(std::string projectName, int experimentNumber)override;		   //Evaluate the accuracy of the model
		[[nodiscard]] bool DownloadModel(std::string projectName, int experimentNumber, std::string destZipDirectory, int modelModel = 0)override;
		[[nodiscard]] std::string ParseTrainingResults(std::string trainingResults)override;
		[[nodiscard]] bool CheckEngineStatus() override;
		[[nodiscard]] bool CheckEngine() override;
		[[nodiscard]] std::string GenerateTestCommand(std::string projectName, int experimentNumber, bool& zipModelExist, const std::string& testDataFolder)override; //Generate the test command

	private:
		std::string yolo11nModelFile;
		std::string ParseMAP(const std::string& text);
		std::string AdjustRootDirectory(const std::string& root);
		std::string GenerateClassNames(std::string labelMapFile);
		std::map<std::string, std::string> ExtractDataFromCfgFile(const std::string& filePath);
		bool GenerateObjectDataFile(std::string sourcePbDataPath, std::string objectDataFile, bool useANSClassFile=false);
		void GenerateTrainDataSet(const std::string& sourceFolder, const std::string& trainFolder, const std::string& testFolder, double trainRatio = 0.8);
		bool GenerateConfigFile(const std::string& templateFile,
			const std::string& outputFile,
			const std::map<std::string, std::string>& replacements);
		int ReadClassesValue(const std::string& filePath);
		int GenerateClassNamesFile(std::string labelMapFile, std::string objectDataFile, bool useANSClassFile);
		void CheckLicense();
		void DeleteWeightsFiles(const std::string& folderPath);
	};
}
#endif
