#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "config.hpp"
#include <any>
#include "dinkyecs.hpp"
#include "components.hpp"


using namespace fmt;
using std::string;

TEST_CASE("basic configuration system", "[config]") {
  Config config("./tests/config.json");

  auto not_found = config["types"]["NOTFOUND"];
  REQUIRE(not_found == nullptr);

  auto test_string = config["types"]["STRING"];
  REQUIRE(test_string ==  L"\u2849█Ω♣");

  std::wstring test_wstring = config.wstring("types", "STRING");
  REQUIRE(test_wstring ==  L"\u2849█Ω♣");

  wchar_t chr0 = test_wstring[0];
  REQUIRE(chr0 == L'\u2849');

  auto test_num = config["types"]["NUMBER"];
  REQUIRE(test_num == 1234);

  auto test_float = config["types"]["FLOAT"];
  REQUIRE(test_num >= 0.1233f);

  auto test_obj = config["types"]["OBJECT"];
  REQUIRE(test_obj["name"] == "Zed");
}

void test_can_ref(Config &ref) {
  REQUIRE(ref["types"]["OBJECT"]["name"] == "Zed");
}

TEST_CASE("can get references of config", "[config]") {
  Config config("./tests/config.json");
  test_can_ref(config);
}

TEST_CASE("store config in any", "[config]") {
  auto as_any = std::make_any<Config>("./tests/config.json");

  Config &cfg = std::any_cast<Config &>(as_any);
  REQUIRE(cfg["types"]["NUMBER"] == 1234);
}

void test_will_live(DinkyECS::World &world) {
  Config config("./tests/config.json");
  world.set_the<Config>(config);
}

TEST_CASE("can go into a world", "[config]") {
  DinkyECS::World world;
  test_will_live(world);
  Config &cfg = world.get_the<Config>();
  REQUIRE(cfg["types"]["NUMBER"] == 1234);
}
