/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "string_utils.h"

#include <fmt/core.h>
#include <fmt/ranges.h>

#include <sstream>
#include <cctype>
#include <algorithm>
#include <ostream>
#include <iomanip>
#include <stdexcept>
#include <ios>
#include <charconv>
#include <string_view>
#ifdef _WIN32
#include <windows.h>
#include <oleauto.h>
#endif

#include <ciso646> // fix windows compiler bug

namespace dhtnet {

#ifdef _WIN32
std::wstring
to_wstring(const std::string& str, int codePage)
{
    int srcLength = (int) str.length();
    int requiredSize = MultiByteToWideChar(codePage, 0, str.c_str(), srcLength, nullptr, 0);
    if (!requiredSize) {
        throw std::runtime_error("Can't convert string to wstring");
    }
    std::wstring result((size_t) requiredSize, 0);
    if (!MultiByteToWideChar(codePage, 0, str.c_str(), srcLength, &(*result.begin()), requiredSize)) {
        throw std::runtime_error("Can't convert string to wstring");
    }
    return result;
}

std::string
to_string(const std::wstring& wstr, int codePage)
{
    int srcLength = (int) wstr.length();
    int requiredSize = WideCharToMultiByte(codePage, 0, wstr.c_str(), srcLength, nullptr, 0, 0, 0);
    if (!requiredSize) {
        throw std::runtime_error("Can't convert wstring to string");
    }
    std::string result((size_t) requiredSize, 0);
    if (!WideCharToMultiByte(
            codePage, 0, wstr.c_str(), srcLength, &(*result.begin()), requiredSize, 0, 0)) {
        throw std::runtime_error("Can't convert wstring to string");
    }
    return result;
}
#endif

std::string
to_string(double value)
{
    char buf[64];
    int len = snprintf(buf, sizeof(buf), "%-.*G", 16, value);
    if (len <= 0)
        throw std::invalid_argument {"can't parse double"};
    return {buf, (size_t) len};
}

std::string
to_hex_string(uint64_t id)
{
    return fmt::format("{:016x}", id);
}

uint64_t
from_hex_string(const std::string& str)
{
    uint64_t id;
    if (auto [p, ec] = std::from_chars(str.data(), str.data()+str.size(), id, 16); ec != std::errc()) {
        throw std::invalid_argument("Can't parse id: " + str);
    }
    return id;
}

std::string_view
trim(std::string_view s)
{
    auto wsfront = std::find_if_not(s.cbegin(), s.cend(), [](int c) { return std::isspace(c); });
    return std::string_view(&*wsfront, std::find_if_not(s.rbegin(),
                                        std::string_view::const_reverse_iterator(wsfront),
                                        [](int c) { return std::isspace(c); })
                           .base() - wsfront);
}

std::vector<unsigned>
split_string_to_unsigned(std::string_view str, char delim)
{
    std::vector<unsigned> output;
    for (auto first = str.data(), second = str.data(), last = first + str.size(); second != last && first != last; first = second + 1) {
        second = std::find(first, last, delim);
        if (first != second) {
            unsigned result;
            auto [p, ec] = std::from_chars(first, second, result);
            if (ec ==  std::errc())
                output.emplace_back(result);
        }
    }
    return output;
}

void
string_replace(std::string& str, const std::string& from, const std::string& to)
{
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
    }
}

std::string_view
string_remove_suffix(std::string_view str, char separator)
{
    auto it = str.find(separator);
    if (it != std::string_view::npos)
        str = str.substr(0, it);
    return str;
}

std::string
string_join(const std::set<std::string>& set, std::string_view separator)
{
    return fmt::format("{}", fmt::join(set, separator));
}

std::set<std::string>
string_split_set(std::string& str, std::string_view separator)
{
    std::set<std::string> output;
    for (auto first = str.data(), second = str.data(), last = first + str.size(); second != last && first != last; first = second + 1) {
        second = std::find_first_of(first, last, std::cbegin(separator), std::cend(separator));
        if (first != second)
            output.emplace(first, second - first);
    }
    return output;
}

} // namespace dhtnet
