#pragma once
#include <string>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <boost/uuid/detail/md5.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/crc.hpp>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/filesystem.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <vector>
#include <locale>
#include <codecvt>
#include <regex>
#include <sstream>
#include <cstdio>
#include <memory>
#include <stdexcept>
#include <array>
#include <cstdlib>

namespace fs = std::filesystem;
std::uint32_t calculateCrc32(const std::string &fileName);
std::string calculateMd5(const std::string &fileName);
std::string calculateSha512(const std::string &fileName);
std::string calculateSha256(const std::string &fileName);
std::string calculateSha1(const std::string &fileName);
bool isSameSha512(std::string checkStr, std::string checkFile);
bool isSameSha256(std::string checkStr, std::string checkFile);
bool isSameSha1(std::string checkStr, std::string checkFile);
bool isSameMD5(std::string checkStr, std::string checkFile);
std::string downloadFiles(const std::string &url, const std::string &localPathStr);
bool isFile(const std::string &path);
std::string getName(const std::string &path);
std::pair<std::string, bool> fileCopy(const std::string &source, const std::string &destination, const std::vector<std::string> &skipPatterns = {});
std::string checkSum(std::string checkSha512String, std::string checkSha256String, std::string checkSha1String, std::string checkMd5String, std::string checkFile);
std::string getFileNameWithoutExtension(const std::string &filePath);
std::pair<std::string, bool> unZip(const std::string &extracThere, const std::string &zipPath);
std::pair<std::string, bool> executeShellScript(const std::string &script);
std::pair<std::string, bool> executeShellScripts(const std::vector<std::string> &scripts);
std::pair<std::string, bool> flattenDirectory(const fs::path &directory, int levels);
