#pragma once

// ==========================================================
// string_utils.hpp - String Manipulation & Hex Formatting
// C++23 Standalone Visual Tool - Poe2VisualTool
// ==========================================================

#include <string>
#include <string_view>
#include <vector>
#include <cstdint>
#include <cstddef>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cctype>

namespace common {

/**
 * @brief Chuyển đổi chuỗi ký tự sang chữ thường (lowercase).
 */
inline std::string ToLower(std::string_view str) {
    std::string res;
    res.reserve(str.size());
    for (char c : str) {
        res.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(c))));
    }
    return res;
}

/**
 * @brief Loại bỏ các ký tự khoảng trắng dư thừa ở đầu và cuối chuỗi.
 */
inline std::string_view Trim(std::string_view str) noexcept {
    const size_t first = str.find_first_not_of(" \t\r\n");
    if (first == std::string_view::npos) return {};
    const size_t last = str.find_last_not_of(" \t\r\n");
    return str.substr(first, last - first + 1);
}

/**
 * @brief Tách chuỗi theo một ký tự phân cách (delimiter).
 */
inline std::vector<std::string> Split(std::string_view str, char delim = ',') {
    std::vector<std::string> result;
    size_t start = 0;
    while (start < str.size()) {
        size_t pos = str.find(delim, start);
        if (pos == std::string_view::npos) {
            result.emplace_back(str.substr(start));
            break;
        }
        result.emplace_back(str.substr(start, pos - start));
        start = pos + 1;
    }
    return result;
}

/**
 * @brief Tách chuỗi theo chuỗi con phân cách (delimiter string).
 */
inline std::vector<std::string> Split(std::string_view str, std::string_view delim) {
    std::vector<std::string> result;
    if (delim.empty()) {
        result.emplace_back(str);
        return result;
    }
    size_t start = 0;
    while (start < str.size()) {
        size_t pos = str.find(delim, start);
        if (pos == std::string_view::npos) {
            result.emplace_back(str.substr(start));
            break;
        }
        result.emplace_back(str.substr(start, pos - start));
        start = pos + delim.size();
    }
    return result;
}

/**
 * @brief Định dạng vùng đệm nhị phân thành chuỗi Hex thập lục phân (uppercase).
 */
inline std::string HexStr(const void* data, size_t len, bool spaceSeparated = true) {
    if (!data || len == 0) return {};
    const auto* bytes = static_cast<const uint8_t*>(data);
    std::ostringstream oss;
    for (size_t i = 0; i < len; ++i) {
        if (i > 0 && spaceSeparated) oss << " ";
        oss << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
            << static_cast<int>(bytes[i]);
    }
    return oss.str();
}

/**
 * @brief Định dạng giá trị số nguyên 64-bit sang chuỗi Hex viết hoa.
 */
inline std::string HexStr(uint64_t v, bool prefix = false, int width = 0) {
    std::ostringstream oss;
    if (prefix) oss << "0x";
    oss << std::hex << std::uppercase;
    if (width > 0) oss << std::setw(width) << std::setfill('0');
    oss << v;
    return oss.str();
}

/**
 * @brief Kiểm tra xem chuỗi có bắt đầu bằng tiền tố (prefix) hay không.
 */
inline bool StartsWith(std::string_view str, std::string_view prefix) noexcept {
    return str.starts_with(prefix);
}

/**
 * @brief Kiểm tra xem chuỗi có kết thúc bằng hậu tố (suffix) hay không.
 */
inline bool EndsWith(std::string_view str, std::string_view suffix) noexcept {
    return str.ends_with(suffix);
}

} // namespace common

using common::ToLower;
using common::Trim;
using common::Split;
using common::HexStr;
using common::StartsWith;
using common::EndsWith;
