#pragma once

#include <algorithm>
#include <cctype>
#include <unordered_map>

#define __INIREADER_H__
#define __INIREADER__
#include <INIReader.h>

#include "TextualValue.hpp"
#include "Vocabulary.hpp"
#include "Utility.hpp"

namespace schneide
{
namespace ini
{

using KeyValueMap = std::unordered_map<std::string, TextualValue>;


/** Immutable value-type that represents a section in the .ini file.
 */
class Section
{
public:
  explicit Section(KeyValueMap content);

  Section(Section&&) = default;
  Section(Section const&) = default;
  Section& operator=(Section&&) = default;
  Section& operator=(Section const&) = default;

  TextualValue const& operator[](std::string key) const
  {
    auto found = mValues->find(toLower(std::move(key)));
    if (found != mValues->end())
      return found->second;
    return mEmpty;
  }

private:
  Ptr<KeyValueMap> mValues;
  TextualValue mEmpty;
};

class Reader
{
public:
  explicit Reader(std::string const& filename);
  ~Reader();

  Section const& operator[](std::string section) const
  {
    auto found = mData.find(toLower(std::move(section)));
    if (found != mData.end())
      return found->second;
    return mEmpty;
  }

private:
  std::unordered_map<std::string, Section> mData;
  Section mEmpty;
};

}  // namespace ini
}  // namespace schneide
