#pragma once
#ifndef UTILITY_H
#define UTILITY_H
#include "ANSLicense.h"
#include <boost/date_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/foreach.hpp"

#include <zlib.h>
#include <zip.h>
#include <filesystem>
#include <cstring>
#include <iostream>
#include <vector>
#include <regex>
#include <stdio.h>
#include <memory>
#include <mutex>

//namespace logging = boost::log;
//namespace attrs = boost::log::attributes;
//namespace expr = boost::log::expressions;
//namespace src = boost::log::sources;
//namespace keywords = boost::log::keywords;
//namespace sinks = boost::log::sinks;

namespace fs = std::filesystem;

#ifndef MIN
#  define MIN(a,b)  ((a) > (b) ? (b) : (a))
#endif
#ifndef MAX
#  define MAX(a,b)  ((a) < (b) ? (b) : (a))
#endif
#define DETECT_BUFFER_SIZE 0x9000


 ANSLICENSE_API std::string path_to_filename(std::string path);
 ANSLICENSE_API std::string GetMainFolderDir();
 ANSLICENSE_API std::string GetLoggerDir();
 ANSLICENSE_API std::string GetLicenseDir();
// Convert file path to only the filename
 ANSLICENSE_API std::wstring String2WString(const std::string input);
 ANSLICENSE_API std::string WString2String(const std::wstring input);
 ANSLICENSE_API std::string Dash2Underscore(std::string text);
 ANSLICENSE_API std::string Underscore2Dash(std::string text);
 ANSLICENSE_API std::string Space2Underscore(std::string text);

 [[nodiscard]] ANSLICENSE_API bool FileExist(const std::string& filePath);
 [[nodiscard]] ANSLICENSE_API bool FolderExist(const std::string& folderPath);
 [[nodiscard]] ANSLICENSE_API bool CreateDirectory(const std::string& folderPath);

 [[nodiscard]] ANSLICENSE_API bool RenameFile(const std::string& oldFilePath, const std::string& newFilePath);
 [[nodiscard]] ANSLICENSE_API bool CopyFile(const std::string& sourceFilePath, const std::string& destinationFilePath);
 ANSLICENSE_API void CopyFiles(const std::string& sourceFolder, const std::string& destinationFolder);
 [[nodiscard]] ANSLICENSE_API bool DeleteFile(const std::string& filePath);
 [[nodiscard]] ANSLICENSE_API bool DeleteLicenseFile(const std::string& filePath);
 [[nodiscard]] ANSLICENSE_API std::vector<std::string> ListFilesInFolder(const std::string& folderPath);
 ANSLICENSE_API void DeleteFilesInFolderExcept(const std::string& folderPath, const std::vector<std::string>& filesToKeep);
 [[nodiscard]] ANSLICENSE_API bool DeleteFolder(const std::string& folderPath);
 ANSLICENSE_API void ToLowerCase(std::string& str);
 ANSLICENSE_API std::string toLower(const std::string& str);
 ANSLICENSE_API std::string GetFileExtension(const std::string& filePath);
 ANSLICENSE_API std::string GetFileNameWithoutExtension(const std::string& filePath);
 ANSLICENSE_API std::string FindFilePathInFileList(const std::vector<std::string>& fileList, const std::string& fileName);
 ANSLICENSE_API std::string ReadFileContent(std::string filePath);
 ANSLICENSE_API std::string ReadFileAsBinary(const std::string& filename);
 ANSLICENSE_API int  ReadAllBytes(std::string filePath, std::vector<char>& allDataBytes);
 ANSLICENSE_API std::string ExtractFolderName(const std::string& filePath); // Function to extract the folder name from a file path or file name
 ANSLICENSE_API std::string GetParentFolder(const std::string& directoryPath);// Function to extract the folder name from a file path or file name
 ANSLICENSE_API std::string CreateFilePath(const std::string& folderName, const std::string& fileName);// Function to create a file path from a folder name and a file name
 ANSLICENSE_API std::filesystem::path GetSafeTempDirectory();
 ANSLICENSE_API std::string GenerateOutputFolder(std::string modelFilePath, std::string modelName, bool edgeDeviceModel=true);
 ANSLICENSE_API bool ExtractPasswordProtectedZip(const std::string& zipFileName, const std::string& password, const std::string& modelName, std::string& outputFolder, bool edgeDeviceModel = true);
 ANSLICENSE_API bool AddFileToZip(zip* archive, const char* filePath, const char* zipPath, const char* password);
 ANSLICENSE_API bool AddFolderContentsToZip(zip* archive, const char* folderPath, const char* zipPath, const char* password);
 ANSLICENSE_API bool ZipFolderWithPassword(const char* folderPath, const char* zipFilePath, const char* password);
 ANSLICENSE_API std::string VectorToCommaSeparatedString(const std::vector<std::string>& inputVector);
 ANSLICENSE_API std::string VectorToSeparatedString(const std::vector<std::string>& inputVector);
 ANSLICENSE_API std::vector<std::string> Split(const std::string str, const std::string regex_str);
 ANSLICENSE_API bool ReadLicenseKeyFile(std::string licenseKeyFilePath, std::string& licenseKey, std::string& activationKey, std::string& validationData);
 ANSLICENSE_API std::vector<std::string> GetTrialLicenseKeyFiles(std::string registrationName);
 ANSLICENSE_API std::string GetTrialLicenseKey(std::string registrationName);
 ANSLICENSE_API bool UpdateTrialLicenseKey(std::string trialLicenseKey, std::string registrationName);
 ANSLICENSE_API int  GetExpirationDate(std::string licenseData, int& productId);
 ANSLICENSE_API bool RemoveTrialLicenseKey(std::string registrationName);
 ANSLICENSE_API std::string GetStringCurrentDateTime(); // Return current datetime in string format
 ANSLICENSE_API std::string GetDateTimeString(const std::string& format);
 // For training engine
 //bool ExtractPasswordProtectedZipForTrainingEgnine(const std::string& zipFileName, const std::string& password, const std::string& modelName, std::string& outputFolder, bool edgeDeviceModel = true);
 ANSLICENSE_API bool ExtractProtectedZipFile(const std::string& zipFileName,const std::string& password,const std::string& modelName,const std::string outputFolder);


#endif