#include "config.hpp"
#include "dbc.hpp"
#include <fmt/core.h>

using nlohmann::json;
using fmt::format;

std::filesystem::path Config::BASE_DIR{"."};

Config::Config(const std::string src_path) : $src_path(src_path) {
  auto path_to = Config::path_to($src_path);
  dbc::check(std::filesystem::exists(path_to),
      fmt::format("requested config file {} doesn't exist", path_to.string()));
  std::ifstream infile(path_to);
  $config = json::parse(infile);
}

nlohmann::json &Config::operator[](size_t key) {
  return $config[key];
}

json &Config::operator[](const std::string &key) {
  dbc::check($config.contains(key), fmt::format("ERROR in config, key {} doesn't exist.", key));
  return $config[key];
}

std::wstring Config::wstring(const std::string main_key, const std::string sub_key) {
  dbc::check($config.contains(main_key), fmt::format("ERROR wstring main/key in config, main_key {} doesn't exist.", main_key));
  dbc::check($config[main_key].contains(sub_key), fmt::format("ERROR wstring in config, main_key/key {}/{} doesn't exist.", main_key, sub_key));

  const std::string& str_val = $config[main_key][sub_key];
  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
  return $converter.from_bytes(str_val);
}

std::vector<std::string> Config::keys() {
  std::vector<std::string> the_fucking_keys;

  for(auto& [key, value] : $config.items()) {
    the_fucking_keys.push_back(key);
  }

  return the_fucking_keys;
}

void Config::set_base_dir(const char *optarg) {
  Config::BASE_DIR.assign(optarg);
}

std::filesystem::path Config::path_to(const std::string& path) {
  return Config::BASE_DIR / path;
}
