/*
 * Copyright (C) 2022 Guido Berhoerster <guido+ubports@berhoerster.name>
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3, as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib-object.h>
#include <json-glib/json-glib.h>

#include "find-helper.h"

GQuark
lps_find_helper_error_quark(void)
{
	return g_quark_from_static_string("lps-find-helper-error-quark");
}

gchar *
find_helper(const gchar *package, const gchar *app, GError **error)
{
	const gchar	*xdg_data_home;
	gchar		*exec_value = NULL;
	gchar		*helpers_data_file = NULL;
	JsonParser	*parser = NULL;
	GError		*tmp_error = NULL;
	gchar		*package_app = NULL;
	JsonReader	*reader = NULL;

	/*
	 * unprivileged helpers for lomiri-push-service are collected
	 * from hook files into a JSON file
	 * $XDG_DATA_HOME/lomiri-push-service/helpers_data.json
	 * See also scripts/click-hook for how this file is generated.
	 */
	/*
	 * NOTE: do not use g_get_user_data_dir() here since it is cached which
	 * leads to problems when testing
	 */
	xdg_data_home = g_getenv("XDG_DATA_HOME");
	helpers_data_file = (xdg_data_home != NULL) ?
	    g_build_filename(xdg_data_home, "lomiri-push-service",
	    "helpers_data.json", NULL) :
	    g_build_filename(g_get_home_dir(), ".local", "share",
	    "lomiri-push-service", "helpers_data.json", NULL);
	parser = json_parser_new();
	json_parser_load_from_file(parser, helpers_data_file, &tmp_error);
	if (tmp_error != NULL) {
		g_propagate_error(error, tmp_error);
		goto out;
	}

	package_app = (app != NULL) ? g_strjoin("_", package, app, NULL) :
	    g_strdup(package);

	/*
	 * The root object contains entries for each click app which provides
	 * an unprivileged helper, it is looked up by name which is either in
	 * the form <package>_<app> or just <package>.  The corresponding
	 * object contains the properties "exec" and "helper_id". The string
	 * "exec" is the path to the unprivileged helper which needs to be
	 * passed to lomiri-app launcher and the "helper_id" string is the
	 * basename of the click hook file.
	 */
	reader = json_reader_new(json_parser_get_root(parser));
	json_reader_read_member(reader, package_app);
	json_reader_read_member(reader, "exec");
	exec_value = g_strdup(json_reader_get_string_value(reader));
	json_reader_end_member(reader);
	if (exec_value == NULL) {
		json_reader_read_member(reader, package);
		json_reader_read_member(reader, "exec");
		exec_value = g_strdup(json_reader_get_string_value(reader));
		json_reader_end_member(reader);
	}
	if (exec_value == NULL) {
		g_set_error(error, LPS_FIND_HELPER_ERROR,
		    LPS_FIND_HELPER_ERROR_NO_HELPER,
		    "no helper found for %s and %s",
		    package_app, package);
	}

out:
	g_clear_object(&reader);
	g_clear_object(&parser);
	g_free(package_app);
	g_free(helpers_data_file);

	return (exec_value);
}
