#include "value.hpp"
#include <format>
#include <iostream>

using namespace sliger;

auto String::at(int32_t index) -> int32_t
{
    if (index >= static_cast<int32_t>(this->value.length()) || index < 0) {
        std::cout << std::format(
            "index not in range, expected to be in range (0..{}), got: {}\n",
            this->value.length() - 1, index);
        exit(1);
    }
    return this->value.at(static_cast<size_t>(index));
}

auto Value::to_string() const -> std::string
{
    switch (this->m_type) {
        case ValueType::Null:
            return "null";
        case ValueType::Int:
            return std::to_string(as_int().value);
        case ValueType::Bool:
            return as_bool().value ? "true" : "false";
        case ValueType::String:
            return std::format("\"{}\"", escape_string(as_string().value));
        case ValueType::Ptr:
            return std::to_string(as_ptr().value);
    }
    std::unreachable();
}

auto Value::to_repr_string() const -> std::string
{
    return std::format(
        "{}({:.4s})", value_type_to_string(this->m_type), to_string());
}

void Value::print_tried_to_unwrap_error_message(ValueType vt) const
{
    std::cerr << std::format("error: tried to unwrap {} as {}\n",
        value_type_to_string(this->m_type), value_type_to_string(vt));
}