/*
 * Copyright 2024 Bloomberg LP
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "buildboxcommontest_utils.h"
#include <buildboxcommon_tomlutils.h>

#include <gtest/gtest.h>

using namespace buildboxcommon;

TEST(TOMLUtilTest, TypeErrorMessage)
{
    try {
        AccessPath path;
        path.emplace_back("foo");
        path.emplace_back(0ul);
        path.emplace_back("bar");
        path.emplace_back(1ul);
        TOMLUtils::throwTOMLTypeError(
            toml::value<bool>(), toml::node_type::table, path, "help-message");
    }
    catch (const std::exception &e) {
        const std::string msg = e.what();
        EXPECT_EQ(
            msg,
            "Invalid TOML input. Begin line 0, column 0, end: line 0, column "
            "0, path: [foo][0][bar][1], expected type: table, help-message");
    }
}

TEST(TOMLUtils, ReadValueFromTable)
{
    const std::string raw = R"(
my-number = 42
my-string = "foo"
  )";
    const auto table = toml::parse(raw);

    AccessPath path;

    const std::optional<int64_t> number =
        TOMLUtils::readOptionalFromTable<int64_t>(
            TOMLUtils::readValue<int64_t>, table, "my-number", path);
    ASSERT_TRUE(number.has_value());
    if (number.has_value()) {
        ASSERT_EQ(number.value(), 42);
    }
    const std::optional<std::string> str =
        TOMLUtils::readOptionalFromTable<std::string>(
            TOMLUtils::readValue<std::string>, table, "my-string", path);
    ASSERT_TRUE(str.has_value());
    if (str.has_value()) {
        ASSERT_EQ(str.value(), "foo");
    }
    const std::optional<std::string> notExist =
        TOMLUtils::readOptionalFromTable<std::string>(
            TOMLUtils::readValue<std::string>, table, "not-exist", path);
    ASSERT_FALSE(notExist.has_value());
    // wrong type
    EXPECT_THROW(TOMLUtils::readOptionalFromTable<double>(
                     TOMLUtils::readValue<double>, table, "my-string", path),
                 std::invalid_argument);
}
