/**
 * config.cpp:
 * parses the config... lol
 **/
#include "core/config.h"
#include "core/strings.h"
#include "core/anime.h"
#include "core/filesystem.h"
#include "core/json.h"
#include "gui/translate/anime.h"
#include "gui/translate/config.h"
#include "ini.h" // mINI
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <limits.h>

/* I'm not exactly fond of using JSON for a config file, but it's better than
   no config I guess. I'd like to have something more readable, e.g. YAML or
   even INI. */

static bool string_to_bool(const std::string& s, bool def = false) {
	bool b;
    std::istringstream is(Strings::ToLower(s));
    is >> std::boolalpha >> b;
    return b;
}

static std::string bool_to_string(bool b) {
	std::ostringstream stream;
	stream << std::boolalpha << b;
	return stream.str();
}

int Config::Load() {
	Filesystem::Path cfg_path = Filesystem::GetConfigPath();
	if (!cfg_path.Exists())
		return 0;
	mINI::INIFile file(cfg_path.GetPath());
	mINI::INIStructure ini;
	file.read(ini);

	service = Translate::ToService(ini.get("General").get("Service"));
	anime_list.language = Translate::ToLanguage(ini.get("Anime List").get("Title language"));
	anime_list.display_aired_episodes = string_to_bool(ini.get("Anime List").get("Display only aired episodes"), true);
	anime_list.display_available_episodes = string_to_bool(ini.get("Anime List").get("Display only available episodes in library"), true);
	anime_list.highlight_anime_if_available = string_to_bool(ini.get("Anime List").get("Highlight anime if available"), true);
	anime_list.highlighted_anime_above_others = string_to_bool(ini.get("Anime List").get("Display highlighted anime above others"));
	anilist.auth_token = ini.get("AniList").get("Auth Token");
	anilist.user_id = Strings::ToInt(ini.get("AniList").get("User ID"));
	theme = Translate::ToTheme(ini.get("Appearance").get("Theme"));

	return 0;
}

int Config::Save() {
	Filesystem::Path cfg_path = Filesystem::GetConfigPath();
	if (!cfg_path.GetParent().Exists())
		cfg_path.GetParent().CreateDirectories();

	mINI::INIFile file(cfg_path.GetPath());
	mINI::INIStructure ini;

	ini["General"]["Service"] = Translate::ToString(service);
	ini["Anime List"]["Title language"] = Translate::ToString(anime_list.language);
	ini["Anime List"]["Display only aired episodes"] = bool_to_string(anime_list.display_aired_episodes);
	ini["Anime List"]["Display only available episodes in library"] = bool_to_string(anime_list.display_available_episodes);
	ini["Anime List"]["Highlight anime if available"] = bool_to_string(anime_list.highlight_anime_if_available);
	ini["Anime List"]["Display highlighted anime above others"] = bool_to_string(anime_list.highlighted_anime_above_others);
	ini["AniList"]["Auth Token"] = anilist.auth_token;
	ini["AniList"]["User ID"] = std::to_string(anilist.user_id);
	ini["Appearance"]["Theme"] = Translate::ToString(theme);

	file.generate(ini);

	return 0;
}
