#pragma once

// ==========================================================
// toml_parser.hpp - Safe Lightweight TOML Configuration Parser
// C++23 Core Engine - AutoPOE2 (DOC-49 & Rule 16)
// ==========================================================

#include <string>
#include <string_view>
#include "common/string_utils.hpp"

namespace common {

/**
 * @brief Trích xuất giá trị số thực (float) từ một dòng cấu hình TOML (dạng key = 12.34).
 * 
 * @param line Dòng văn bản chứa cấu hình TOML.
 * @param key Tên khóa (key) cần tìm kiếm.
 * @param[out] outVal Biến nhận giá trị số thực float nếu phân tích thành công.
 * @return true nếu tìm thấy khóa và trích xuất thành công, false nếu ngược lại.
 * 
 * @code
 * float width = 0.0f;
 * if (common::ParseTomlFloat("reference_width = 1920.0", "reference_width", width)) {
 *     // width == 1920.0f
 * }
 * @endcode
 */
inline bool ParseTomlFloat(std::string_view line, std::string_view key, float& outVal) noexcept {
    size_t pos = line.find(key);
    if (pos == std::string_view::npos) return false;
    size_t eq = line.find('=', pos);
    if (eq == std::string_view::npos) return false;

    std::string_view valPart = Trim(line.substr(eq + 1));
    if (valPart.empty()) return false;

    try {
        outVal = std::stof(std::string(valPart));
        return true;
    } catch (...) {
        return false;
    }
}

/**
 * @brief Trích xuất giá trị số nguyên có dấu (int) từ một dòng cấu hình TOML.
 * 
 * @param line Dòng văn bản chứa cấu hình TOML.
 * @param key Tên khóa (key) cần tìm kiếm.
 * @param[out] outVal Biến nhận giá trị int nếu phân tích thành công.
 * @return true nếu trích xuất thành công, false nếu thất bại.
 */
inline bool ParseTomlInt(std::string_view line, std::string_view key, int& outVal) noexcept {
    size_t pos = line.find(key);
    if (pos == std::string_view::npos) return false;
    size_t eq = line.find('=', pos);
    if (eq == std::string_view::npos) return false;

    std::string_view valPart = Trim(line.substr(eq + 1));
    if (valPart.empty()) return false;

    try {
        outVal = std::stoi(std::string(valPart));
        return true;
    } catch (...) {
        return false;
    }
}

/**
 * @brief Trích xuất giá trị số nguyên không dấu (uint32_t) từ một dòng cấu hình TOML.
 * 
 * @param line Dòng văn bản chứa cấu hình TOML.
 * @param key Tên khóa (key) cần tìm kiếm.
 * @param[out] outVal Biến nhận giá trị uint32_t nếu phân tích thành công.
 * @return true nếu trích xuất thành công, false nếu thất bại.
 */
inline bool ParseTomlUint(std::string_view line, std::string_view key, uint32_t& outVal) noexcept {
    size_t pos = line.find(key);
    if (pos == std::string_view::npos) return false;
    size_t eq = line.find('=', pos);
    if (eq == std::string_view::npos) return false;

    std::string_view valPart = Trim(line.substr(eq + 1));
    if (valPart.empty()) return false;

    try {
        outVal = static_cast<uint32_t>(std::stoul(std::string(valPart)));
        return true;
    } catch (...) {
        return false;
    }
}

/**
 * @brief Trích xuất giá trị boolean từ một dòng cấu hình TOML (hỗ trợ true/false, 1/0, yes/no).
 * 
 * @param line Dòng văn bản chứa cấu hình TOML.
 * @param key Tên khóa (key) cần tìm kiếm.
 * @param[out] outVal Biến nhận giá trị bool nếu phân tích thành công.
 * @return true nếu trích xuất thành công, false nếu thất bại.
 */
inline bool ParseTomlBool(std::string_view line, std::string_view key, bool& outVal) noexcept {
    size_t pos = line.find(key);
    if (pos == std::string_view::npos) return false;
    size_t eq = line.find('=', pos);
    if (eq == std::string_view::npos) return false;

    std::string_view valPart = Trim(line.substr(eq + 1));
    std::string v = ToLower(valPart);
    if (v == "true" || v == "1" || v == "yes") {
        outVal = true;
        return true;
    }
    if (v == "false" || v == "0" || v == "no") {
        outVal = false;
        return true;
    }
    return false;
}

/**
 * @brief Trích xuất giá trị chuỗi (string) từ một dòng cấu hình TOML (tự động loại bỏ dấu nháy kép/đơn).
 * 
 * @param line Dòng văn bản chứa cấu hình TOML.
 * @param key Tên khóa (key) cần tìm kiếm.
 * @param[out] outVal Biến nhận chuỗi kết quả nếu phân tích thành công.
 * @return true nếu trích xuất thành công, false nếu thất bại.
 */
inline bool ParseTomlString(std::string_view line, std::string_view key, std::string& outVal) {
    size_t pos = line.find(key);
    if (pos == std::string_view::npos) return false;
    size_t eq = line.find('=', pos);
    if (eq == std::string_view::npos) return false;

    std::string_view valPart = Trim(line.substr(eq + 1));
    if (valPart.size() >= 2 && ((valPart.front() == '"' && valPart.back() == '"') ||
                                (valPart.front() == '\'' && valPart.back() == '\''))) {
        valPart = valPart.substr(1, valPart.size() - 2);
    }
    outVal = std::string(valPart);
    return true;
}

} // namespace common

using common::ParseTomlFloat;
using common::ParseTomlInt;
using common::ParseTomlUint;
using common::ParseTomlBool;
using common::ParseTomlString;
