#pragma once

#include <toml.h>
#include <fstream>
#include <filesystem>
#include <optional>
#include "../server/config.hpp"
#include "../client/config.hpp"

namespace config {

constexpr auto DEFAULT_FILE = "config.toml";

/// Savable game options
struct options {
public:
    /// Load from path
    options(const std::string &path): path(path) {
        auto config = [&] {
            if(std::filesystem::exists(path))
                return toml::parse_file(path);

            LOG_E("Config file " << path << " not found. Creating default");
            return toml::table();
        }();
        if (config["server"]["enabled"].value_or(true)) {
            _server = server::options(config["server"]);
        }
        if(config["client"]["enabled"].value_or(true)) {
            _client = client::options(config["client"]);
        }
    }
    /// Write to path
    void save() {
        auto config = toml::table();
        config.insert_or_assign("client", _client.has_value() ? _client.value().save() : toml::table({{"enabled", false}}));
        config.insert_or_assign("server", _server.has_value() ? _server.value().save() : toml::table({{"enabled", false}}));

        std::ofstream out;
        out.open(path, std::ios::out | std::ios::trunc);
        out << config << "\n\n";
        out.close();
    }

    constexpr bool hasServer() const { return _server.has_value(); }
    constexpr bool hasClient() const { return _client.has_value(); }
    server::options &getServer() { return _server.value(); }
    client::options &getClient() { return _client.value(); }

private:
    std::string path;
    std::optional<server::options> _server;
    std::optional<client::options> _client;
};

}