/*
 * SPDX-FileCopyrightText: 2025 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#include "catch2_common.h"

#include <tango/internal/parse.h>

#include <clocale>
#include <limits>
#include <string>

template <typename T>
void test_parse_value(T value)
{
    std::string prev_locale = std::setlocale(LC_NUMERIC, nullptr);
    std::setlocale(LC_NUMERIC, "C");
    std::string buf = std::to_string(value);
    std::setlocale(LC_NUMERIC, prev_locale.c_str());

    REQUIRE_NOTHROW(parse_as<T>(buf));
}

template <typename T>
void test_parse_int()
{
    REQUIRE_THROWS(parse_as<T>(""));
    REQUIRE_THROWS(parse_as<T>("1_"));
    REQUIRE_NOTHROW(parse_as<T>("0"));
    test_parse_value<T>(std::numeric_limits<T>::min());
    test_parse_value<T>(std::numeric_limits<T>::max());
}

template <typename T>
void test_parse_float()
{
    REQUIRE_THROWS(parse_as<T>(""));
    REQUIRE_THROWS(parse_as<T>("1.1_"));
    REQUIRE_NOTHROW(parse_as<T>("0"));
    REQUIRE_NOTHROW(parse_as<T>("0.0"));
    test_parse_value<T>(std::numeric_limits<T>::min());
    test_parse_value<T>(std::numeric_limits<T>::max());
    test_parse_value<T>(std::numeric_limits<T>::min_exponent);
    test_parse_value<T>(std::numeric_limits<T>::max_exponent);
}

SCENARIO("integers and floats can be parsed")
{
    test_parse_int<int>();
    test_parse_int<unsigned int>();
    test_parse_int<long>();
    test_parse_int<unsigned long>();
    test_parse_float<double>();
}
