#include <cstring>
#include <gio/gio.h>
#include <string_view>

/* this file uses the regular gio C interface because I don't
 * see any real benefit to using the C++ bindings. */

namespace glib {

bool IsInDarkTheme() {
	GSettings* settings = ::g_settings_new("org.gnome.desktop.interface");
	if (!settings)
		return false;

	{
		GVariant* val = ::g_settings_get_value(settings, "color-scheme");
		if (!val) {
			::g_object_unref(settings);
			return false;
		}

		const gchar* str = nullptr;
		::g_variant_get(val, "&s", &str); /* should not be freed */
		if (!str) {                       /* how */
			::g_variant_unref(val);
			::g_object_unref(settings);
			return false;
		}

		bool success = !std::strcmp(str, "prefer-dark");

		::g_variant_unref(val);

		if (success)
			return true;
	}

	{
		GVariant* gtk_theme = ::g_settings_get_value(settings, "gtk-theme");
		if (!gtk_theme) {
			::g_object_unref(settings);
			return false;
		}

		const gchar* gtk_theme_str = nullptr;
		::g_variant_get(gtk_theme, "&s", gtk_theme_str);
		if (!gtk_theme_str) {
			::g_variant_unref(gtk_theme);
			::g_object_unref(settings);
			return false;
		}

		static constexpr std::string_view suffix = "-dark";

		size_t gtk_theme_len = strlen(gtk_theme_str);

		if (gtk_theme_len < suffix.length()) {
			::g_variant_unref(gtk_theme);
			::g_object_unref(settings);
			return false;
		}

		bool success = !std::strncmp(gtk_theme_str + gtk_theme_len - suffix.length(), suffix.data(), suffix.length());

		::g_variant_unref(gtk_theme);
		::g_object_unref(settings);

		if (success)
			return true;
	}

	return false;
}

} // namespace glib
