#include "config.h"
#include <cassert>

#ifdef USE_BOOST_FILESYSTEM
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif

CServerConfig::CServerConfig() = default;

CServerConfig::~CServerConfig() = default;

bool CServerConfig::baseInit()
{
    fs::path tpath(COfPath::get_config_dir("transm", true));
    config_path_ = tpath.append("transm.ini").string();
    if (!fs::exists(config_path_)) {
        gen_default_ini(config_path_);
    }
    SI_Error ret = ini_handle_.LoadFile(config_path_.c_str());
    if (ret != SI_OK) {
        mperror("Load Ini [{}] Failed.", config_path_);
        return false;
    }
    init_ = true;
    return true;
}

bool CServerConfig::read_ini(std::vector<TransmSet>& set)
{
    assert(init_ == true);
    long groups = ini_handle_.GetLongValue("BASE", "GROUPS");
    if (groups < 1) {
        mperror("GROUPS num < 1.");
        return false;
    }
    set.clear();
    for (long i = 0; i < groups; ++i) {
        std::string key = "GROUP" + std::to_string(i);
        TransmSet ts;
        ts.group = key;
        ts.grp_id = i;
        ts.ip = ini_handle_.GetValue(key.c_str(), "IP");
        ts.port = ini_handle_.GetLongValue(key.c_str(), "PORT");
        set.push_back(ts);
    }
    return true;
}

bool CServerConfig::write_ini(const std::vector<TransmSet>& set)
{
    assert(init_ == true);
    for (size_t start = 0; start < set.size(); ++start) {
        std::string key = "GROUP" + std::to_string(start);
        ini_handle_.SetValue(key.c_str(), "IP", set[start].ip.c_str());
        ini_handle_.SetLongValue(key.c_str(), "PORT", set[start].port);
    }
    ini_handle_.SaveFile(config_path_.c_str());
    return true;
}

bool CServerConfig::append_ini(const std::string& ip, long port)
{
    assert(init_ == true);
    int group = ini_handle_.GetLongValue("BASE", "GROUPS");
    std::string node_name = "GROUP" + std::to_string(group);
    ini_handle_.SetValue(node_name.c_str(), "IP", ip.c_str());
    ini_handle_.SetLongValue(node_name.c_str(), "PORT", port);
    ini_handle_.SetLongValue("BASE", "GROUPS", group + 1);
    ini_handle_.SaveFile(config_path_.c_str());
    return true;
}

bool CServerConfig::remove_ini(long num)
{
    assert(init_ == true);
    std::vector<TransmSet> set;
    if (!read_ini(set)) {
        return false;
    }
    set.erase(
        std::remove_if(set.begin(), set.end(), [&num](const TransmSet& item) { return item.grp_id == num; }),
        set.end());
    ini_handle_.Reset();
    ini_handle_.SetLongValue("BASE", "GROUPS", static_cast<long>(set.size()));
    return write_ini(set);
}

bool CServerConfig::get_ini(const std::vector<TransmSet>& set, long num, TransmSet& use)
{
    bool find = false;
    for (const auto& item : set) {
        if (item.grp_id == num) {
            find = true;
            use = item;
            break;
        }
    }
    return find;
}

void CServerConfig::gen_default_ini(const std::string& path)
{
    mpwarn("Gen Default Setting Ini in [{}].", path);
    ini_handle_.LoadFile(path.c_str());
    ini_handle_.SetLongValue("BASE", "GROUPS", 1);
    ini_handle_.SetValue("GROUP0", "IP", "127.0.0.1");
    ini_handle_.SetValue("GROUP0", "PORT", "9898");
    ini_handle_.SaveFile(path.c_str());
}