#include "AppConfig.h"
#include "util.h"
#include <fstream>


AppConfig::AppConfig()
: _fileName(L"AppConfig.ini")
{
    _readFile(_fileName.c_str());
}

AppConfig::~AppConfig()
{
    _writeFile(_fileName.c_str());
}

AppConfig& AppConfig::instance()
{
    static AppConfig appConfig;
    return appConfig;
}

void AppConfig::flush()
{
    _writeFile(_fileName.c_str());
}

void AppConfig::_readFile(const wchar_t* fileName)
{
    _fileName = fileName;
    _entries.clear();

    std::wfstream file;
    file.open(fileName, std::ios::in);

    if (!file.is_open())
        return;

    std::wstring line = L"";
    std::wstring section = L"";

    while (getline(file, line)) {
        line = util::trim(line);

        if (line.empty())
            continue;

        if (*(line.begin()) == L'[') {
            section = util::trim(line, L" []");
        }

        else {
            size_t equals = line.find_first_of(L"=");

            if (equals == std::wstring::npos)
                continue;

            std::wstring attribute = line.substr(0, equals);
            std::wstring value = line.substr(equals + 1);

            attribute = util::trim(attribute);
            value = util::trim(value);
            
            std::map<std::wstring, std::map<std::wstring, std::wstring>>::iterator iSection = _entries.find(section);

            if (iSection != _entries.end()) {
                iSection->second.insert(std::pair<std::wstring, std::wstring>(attribute, value));
            }
            else if (section != L"") {
                std::map<std::wstring, std::wstring> sectionMap;
                sectionMap.insert(std::pair<std::wstring, std::wstring>(attribute, value));
                _entries.insert(std::pair<std::wstring, std::map<std::wstring, std::wstring>>(section, sectionMap));
            }
        }

    }

    file.close();
}

void AppConfig::_writeFile(const wchar_t* fileName)
{
    _fileName = fileName;

    std::wfstream file;
    file.open(fileName, std::ios::out);

    if (!file.is_open())
        return;

    for (std::map<std::wstring, std::map<std::wstring, std::wstring>>::iterator iSection = _entries.begin(); iSection != _entries.end(); ++iSection) {
        file << L"[" << iSection->first << L"]" << std::endl;

        for (std::map<std::wstring, std::wstring>::iterator iAttribute = iSection->second.begin(); iAttribute != iSection->second.end(); ++iAttribute) {
            file << iAttribute->first << L" = " << iAttribute->second << std::endl;
        }

        file << std::endl;
    }

    file.close();
}

const wchar_t* AppConfig::getFileName() const
{
    return _fileName.c_str();
}