#include "INIReader.hpp"
#include <spdlog/fmt/fmt.h>

using namespace schneide;
using namespace schneide::ini;

namespace
{
using SectionedKeyValueMap =
  std::unordered_map<std::string, ini::KeyValueMap>;

int ValueHandler(
  void* user, const char* section, const char* name, const char* value)
{
  SectionedKeyValueMap& map = *(SectionedKeyValueMap*)user;
  map[toLower(section)].insert(
    std::make_pair(toLower(name), value));
  return 1;
}

}  // namespace

Reader::Reader(std::string const& filename) : mEmpty({})
{
  // Read the data into the local map
  SectionedKeyValueMap sections;
  auto error = ini_parse(filename.c_str(), &::ValueHandler, &sections);
  if (error)
  {
    if (error > 0)
    {
      throw std::runtime_error(
        fmt::format("Parse error in file {0} line {1}", error, filename));
    }
    else
    {
      throw std::runtime_error(
        fmt::format("Unable to open file {0}", filename));
    }
  }

  // Move data into this instance
  for (auto& section : sections)
  {
    mData.insert(
      std::make_pair(section.first, Section(std::move(section.second))));
  }
}

Reader::~Reader() = default;

Section::Section(KeyValueMap content)
: mValues(std::make_shared<KeyValueMap>(std::move(content)))
{
}
