/*========================== begin_copyright_notice ============================
Copyright (C) 2021-2025 Intel Corporation

SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/

#ifndef GTPIN_CRT_UTILS_H_
#define GTPIN_CRT_UTILS_H_

#if defined(__cplusplus)

#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cstdint>

namespace gtpin
{

/* ============================================================================================= */
// String utilities
/* ============================================================================================= */
/// Convert an integer to a decimal representation string
template<typename T> inline std::string DecStr(const T& num, uint32_t width = 0)
{
    std::stringstream s; s << std::setw(width) << num; return s.str();
}

/// Convert an unsigned integer to a hexadecimal representation string
template<typename T> inline std::string HexStr(const T& num, uint32_t width = 0)
{
    std::stringstream s; s << std::hex << std::setw(width) << std::setfill('0') << std::right << num; return s.str();
}
template<typename T> inline std::string HexStr(T* const& ptr, uint32_t width = 0)
{
    return HexStr(reinterpret_cast<uintptr_t>(ptr), width);
}

std::string ToLower(const std::string& str);    ///< Transform string characters to lowercase
std::string ToUpper(const std::string& str);    ///< Transform string characters to uppercase

/// Split the specified string into tokens separated by the specified delimiter
void SplitString(const std::string& str, const char delim, std::vector<std::string>& tokens);

/// Trim leading and trailing characters 'tr' of the string
std::string TrimString(const std::string& str,  char tr = ' ');

/// Remove trailing 'tr' characters of the string
std::string RemoveTrailing(const std::string& str,  char tr = ' ');

/// Replace spaces with the character 'sep' in the string 'str'. @return the resulting string
std::string GlueString(const std::string& str, char sep = '_');

/// Convert string 'str' to integer 'res'.  @retrun true if 'str' is convertible to integer
bool StrToInt(const std::string& str, uint32_t& res);

/* ============================================================================================= */
// File system utilities
/* ============================================================================================= */
/// @return Separator of directory/file names in the file path
char PathSeparator();

/*!
 * Create a directory with the specified name. Do nothing if directory has already been created.
 * @return success/failure status
 */
bool MakeDirectory(const std::string& dir);

/*!
 * Create a directory named 'subDir' under the directory 'dir'.
 * @return Full path to the created directory, or empty string in case of failure.
 */
std::string MakeSubDirectory(const std::string& dir, const std::string& subDir);

/// @return Absolute (full) pathname that refers to the directory/file specified by 'path'
std::string GetFullPath(const std::string& path);

/// @return true if the specified path is relative (not full)
bool IsRelativePath(const std::string& path);

/// @return Name of the leaf (base) directory in the given a pathname
std::string GetBaseDirectory(const std::string& path);

/// Extract file name, including suffix, from the specified path
std::string GetFilenameFromPath(const std::string& path);

/// @return true, if specified pathnames refer to the same directory/file
bool CmpPathnames(const std::string& path0, const std::string& path1);

/// Convert specified string into valid filename. Transform forbidden characters into underscore ('_') symbols.
std::string NormalizeFilename(const std::string& filename, const std::string& extension = "");

/// @return A file/directory path composed of specified names and system path separators
template<typename T>
inline std::string JoinPath(const T& a)
{
    return a;
}
template<typename T1, typename T2, typename ... Args>
inline std::string JoinPath(const T1& a, const T2& b, const Args&... args)
{
    return a + std::string(1, PathSeparator()) + JoinPath(b, args...);
}

}
#endif
#endif
