#include "IniFileReader.h"
#include "Util.h"


IniFile IniFileReader(const char* a_fileName)
{
  IniFile iniData;
  iniData.fileName = a_fileName;

	FILE* f = 0;
	fopen_s(&f, a_fileName, "rb");
	if (!f)
  {
    printf("Error, unable to open %s for reading\n", a_fileName);
    return iniData;
  }

  int currentLine = 0;
  char lineBuf[1024];
  bool first = true;
  while ( fgets(lineBuf, sizeof(lineBuf), f) )
  {
    currentLine++;
    std::string line = lineBuf;
    if (trim(line).empty())
    {
    }
    else if (lineBuf[0] == '[')
    {
      int endOfSectionName = 1;
      while (lineBuf[endOfSectionName])
      {
        if (lineBuf[endOfSectionName] == ']')
        {
          break;
        }
        endOfSectionName++;
      }
      IniSection newSection;
      newSection.name = std::string(lineBuf + 1, endOfSectionName - 1); 
      //printf("section name: -%s-\n", newSection.name.c_str());
      iniData.sections.push_back(newSection);
    }
    else
    {
      if (iniData.sections.size())
      {
				std::vector<std::string> strs = split(line, '=');
				if (strs.size() != 2)
				{
				  printf("Error: %s:%i  error parsing line, no '=' in line. -%s-\n", a_fileName, currentLine, lineBuf);
				}
        else
        {
          IniValue value;
          value.name = trim(strs[0]);
          value.value = trim(strs[1]);
          iniData.sections.back().values.push_back(value);
        }
      }
      else
      {
        printf("Error: %s:%i  section data before section started\n", a_fileName, currentLine);
      }
    }
  }
	fclose(f);
  return iniData;
}


std::map<std::string,std::string> IniSectionAsMap(const IniSection& section)
{
  std::map<std::string,std::string> asMap;
  for (const IniValue& val : section.values)
  {
    asMap[val.name] = val.value;
  }
  return asMap;
}


std::map<std::string,IniSection> IniFileAsMap(const IniFile& file)
{
  std::map<std::string,IniSection> asMap;
  for (const IniSection& section : file.sections)
  {
    asMap[section.name] = section;
  }
  return asMap;
}


void IniSectionAddValue(IniSection& section, std::string name, std::string value)
{
  IniValue val;
  val.name = name;
  val.value = value;
  section.values.push_back(val);
}


IniFile IniFileFromMap(const std::map<std::string,IniSection>& iniMap)
{
  IniFile iniData;
  for (const auto& ent : iniMap)
  {
    IniSection newSection = ent.second;
    newSection.name = ent.first;
    printf("adding section to ini %s\n", newSection.name.c_str());
    iniData.sections.push_back(newSection);
  }
  return iniData;
}


bool IniFileWriter(const char* a_fileName, const IniFile& iniFile)
{
	FILE* f = 0;
	fopen_s(&f, a_fileName, "w");
	if (!f)
  {
    printf("Error, unable to open %s for writing\n", a_fileName);
    return false;
  }

  for (const IniSection& sec : iniFile.sections)
  {
    fprintf(f, "\n[%s]\n", sec.name.c_str());
    for (const IniValue& val : sec.values)
    {
      fprintf(f, "%s=%s\n", val.name.c_str(), val.value.c_str());
    }
  }
	fclose(f);
  return true;
}


