#include "tile/base/encoding/hex.h"

#include "tile/base/encoding/detail/hex_chars.h"
#include "tile/base/internal/logging.h"
#include "tile/base/string.h"

namespace tile {

std::string
EncodeHex(Slice from, bool uppercase)
{
    std::string result;
    EncodeHex(from, &result, uppercase);
    return result;
}

std::optional<std::string>
DecodeHex(Slice from)
{
    std::string result;
    if (!DecodeHex(from, &result)) { return std::nullopt; }
    return result;
}

void
EncodeHex(Slice from, std::string *to, bool uppercase)
{
    to->clear();
    to->reserve(from.size() * 2);
    for (auto &&e : from) {
        // auto index = static_cast<std::uint8_t>(e);
        auto pair = detail::AsciiCodeToCharPair(static_cast<std::uint8_t>(e), uppercase);
        to->append({pair.first, pair.second});
    }
}

bool
DecodeHex(Slice from, std::string *to)
{
    if (from.size() % 2 != 0) { return false; }

    to->clear();
    to->reserve(from.size() / 2);
    for (size_t i = 0; i != from.size(); i += 2) {
        auto v = detail::AsciiCodeFromCharPair(from[i], from[i + 1]);
        if (v == -1) { return false; }

        TILE_CHECK(v >= 0 && v <= 255);
        to->push_back(v);
    }

    return true;
}
}// namespace tile
